React停止该元素上的其他事件

Mar*_*son 6 html javascript css events reactjs

我有一个音量元素,当用户将鼠标悬停在音量栏上时会显示音量条.这一切都适用于桌面.但是,要在移动设备上获得相同的功能,用户可以点击volume元素,该元素也会切换静音点击事件.

当用户在移动设备上点击(即点按)该元素时,我想要停止该静音事件.

我不想修改Mute或VolumeBar类来修复它,因为这些是我的库中开发人员使用的泛型类.

https://jsfiddle.net/jwm6k66c/2145/

  • 实际:触发静音点击事件并打开音量栏.
  • 预期:静音点击事件不会被触发,音量栏会打开.

打开控制台 - >进入移动视图(Chrome上的CTRL + SHIFT + M) - >单击音量按钮并观察控制台日志.

我尝试过的:

使用volumeControlOnClick停止传播史时,音量条的高度为0(即不可见),这不,虽然取消的onClick.

我想要的是:

如果用户第一次在移动设备中单击音量图标,则取消静音点击事件.相反,它应该只显示音量条.

const volumeControlOnClick = (e) => {
  const volumeBarContainer =
    e.currentTarget.nextElementSibling.querySelector('.jp-volume-bar-container');
  /* Stop propogation is for mobiles to stop
    triggering mute when showing volume bar */
  if (volumeBarContainer.clientHeight === 0) {
    e.stopPropagation();
    console.log("stop propogation")
  }
};

class Volume extends React.Component {
  constructor(props) {
    super(props);

    this.state = {};
  }
    render() {
    return (
        <div className="jp-volume-container">
        <Mute onTouchStart={volumeControlOnClick}><i className="fa fa-volume-up" /></Mute>
        <div className="jp-volume-controls">
          <div className="jp-volume-bar-container">
            <VolumeBar />
          </div>
         </div>
       </div>
    );
  }
};

class Mute extends React.Component {
    render() {
    return (
      <button className="jp-mute" onClick={() => console.log("mute toggled")} onTouchStart={this.props.onTouchStart}>
        {this.props.children}
      </button>
    );
  }
};

class VolumeBar extends React.Component {
    render() {
    return (
        <div className="jp-volume-bar" onClick={() => console.log("bar moved")}>
        {this.props.children}
      </div>
    );
  }
};

React.render(<Volume />, document.getElementById('container'));
Run Code Online (Sandbox Code Playgroud)

Mar*_*son 2

这就是我最终得到的结果。它之所以有效,onTouchStart是因为如果它是触摸事件,则总是在之前调用onClick,如果不是,则无论如何都会调用自定义逻辑。它也会在悬停发生之前触发。这保留了 :hover 事件。e.preventDefault()没有。

let isVolumeBarVisible;

const onTouchStartMute = e => (
  isVolumeBarVisible = e.currentTarget.nextElementSibling
    .querySelector('.jp-volume-bar-container').clientHeight > 0
);

const onClickMute = () => () => {
  if (isVolumeBarVisible !== false) {
    // Do custom mute logic
  }
  isVolumeBarVisible = undefined;
};

<Mute
  aria-haspopup onTouchStart={onTouchStartMute}
  onClick={onClickMute}
>
  <i className="fa">{/* Icon set in css*/}</i>
</Mute>
Run Code Online (Sandbox Code Playgroud)