繁体   English   中英

如何将相同的事件处理程序用于click和touchend事件,但仅运行其中之一?

[英]How to use same event handler for click and touchend events but only run one of them?

这是我正在使用https://repl.it/repls/AdoredMundaneFinance#index.js的叠加控件的代码。 您可以尝试与之交互以查看其提供的功能。

我遇到了一个问题,即在触摸设备上触发touchend的事件和click都被触发了。 现在我已经用谷歌搜索了很多,

一种。 由于用户体验原因,我不想节制 尝试过,不喜欢它。

b。 尝试过event.preventDefault() ,它确保仅使用一个事件,但会阻止事件到达目标子级,即应该接收这些点击/轻击的子级div,因此不能使用它。

C。 我尝试了event.stopPropogation(),但这引起了其他问题,我什至尝试仅在事件可取消时才调用它,您可以尝试看看我要说的是什么。

d。 我现在正在尝试检测设备是否为触摸设备并基于该分配功能,但是我也不想将问题也扩展到触摸检测,因为没有“真正的”检测方法,我不会想要冒险。 如果有人在触摸设备上使用鼠标并且触发了点击该怎么办? 等等等

请帮忙。

反应:

class App extends React.Component {
  constructor() {
    super();
    this.hideAfterXTimeout = null;
    this.state = {
      visible: false
    };
  }

  overlayRef(ref) {
    if (!this.overlay) {
      this.overlay = ref;
      this.overlay.addEventListener("click", this.clickTouchEffect.bind(this));
      this.overlay.addEventListener(
        "touchend",
        this.clickTouchEffect.bind(this)
      );
      let throttledHandler = this.throttle(300, this.mouseMoveEffect.bind(this));
            this.overlay.addEventListener(
        "mousemove",
        throttledHandler.bind(this)
      );
    }
  }

  mouseMoveEffect(event) {
    console.dir("called");
    this.showControls();
  }

  clickTouchEffect(event) {
    if (!event.target.hasAttribute("data-video")) {
      if (this.state.visible) {
        this.hideControls();
      } else {
        this.showControls();
      }
    } else {
      this.showControls();
    }
  }

  throttle(delay, fn) {
    let lastCall = 0;
    return function (...args) {
      const now = (new Date).getTime();
      if (now - lastCall < delay) {
        return;
      }
      lastCall = now;
      return fn(...args);
    }
  }

  showControls() {
    if(this.state.visible !== true){
      this.setState({
        visible: true
      });
    }
    if (this.hideAfterXTimeout) {
      clearTimeout(this.hideAfterXTimeout);
      this.hideAfterXTimeout = null;
    }
    let _me = this;
    this.hideAfterXTimeout = setTimeout(() => {
      _me.hideControls();
    }, 5000);
    this.overlay.classList.remove("hide");
  }

  hideControls() {
    this.setState({
      visible: false
    });
    if (this.hideAfterXTimeout) {
      clearTimeout(this.hideAfterXTimeout);
      this.hideAfterXTimeout = null;
    }
    this.overlay.classList.add("hide");
  }

  cc(){
    console.log("clicked");
  }

  render() {
    return (
      <div ref={this.overlayRef.bind(this)} className="overlay hide">
      <div className="visibility">
        <div onClick={this.cc.bind(this)} data-video="control" className="controls">
          CC
        </div>
      </div>
      </div>
    );
  }
}


ReactDOM.render(<App />, document.getElementById('app'));

CSS:

.App {
  font-family: sans-serif;
  text-align: center;
}

.overlay {
  width: 720px;
  height: 405px;
  outline: 1px solid red;

  opacity: 1;
  visibility: visible;
  transition: 0.3s ease-out opacity;
}

.overlay.hide {
  opacity: 0;
}

.overlay.hide > .visibility {
  visibility: hidden;
}

.overlay > .visibility {
  visibility: visible;
}

.controls {
  width: 64px;
  height: 64px;
  outline: 1px solid blue;

这是我正在使用https://repl.it/repls/AdoredMundaneFinance#index.js的叠加控件的代码。 您可以尝试与之交互以查看其提供的功能。

我遇到了一个问题,即在触摸设备上触发touchend的事件和click都被触发了。 现在我已经用谷歌搜索了很多,

一种。 由于用户体验原因,我不想节制 尝试过,不喜欢它。

b。 尝试过event.preventDefault() ,它确保仅使用一个事件,但会阻止事件到达目标子级,即应该接收这些点击/轻击的子级div,因此不能使用它。

C。 我尝试了event.stopPropogation(),但这引起了其他问题,我什至尝试仅在事件可取消时才调用它,您可以尝试看看我要说的是什么。

d。 我现在正在尝试检测设备是否为触摸设备并基于该分配功能,但是我也不想将问题也扩展到触摸检测,因为没有“真正的”检测方法,我不会想要冒险。 如果有人在触摸设备上使用鼠标并且触发了点击该怎么办? 等等等

请帮忙。

反应:

class App extends React.Component {
  constructor() {
    super();
    this.hideAfterXTimeout = null;
    this.state = {
      visible: false
    };
  }

  overlayRef(ref) {
    if (!this.overlay) {
      this.overlay = ref;
      this.overlay.addEventListener("click", this.clickTouchEffect.bind(this));
      this.overlay.addEventListener(
        "touchend",
        this.clickTouchEffect.bind(this)
      );
      let throttledHandler = this.throttle(300, this.mouseMoveEffect.bind(this));
            this.overlay.addEventListener(
        "mousemove",
        throttledHandler.bind(this)
      );
    }
  }

  mouseMoveEffect(event) {
    console.dir("called");
    this.showControls();
  }

  clickTouchEffect(event) {
    if (!event.target.hasAttribute("data-video")) {
      if (this.state.visible) {
        this.hideControls();
      } else {
        this.showControls();
      }
    } else {
      this.showControls();
    }
  }

  throttle(delay, fn) {
    let lastCall = 0;
    return function (...args) {
      const now = (new Date).getTime();
      if (now - lastCall < delay) {
        return;
      }
      lastCall = now;
      return fn(...args);
    }
  }

  showControls() {
    if(this.state.visible !== true){
      this.setState({
        visible: true
      });
    }
    if (this.hideAfterXTimeout) {
      clearTimeout(this.hideAfterXTimeout);
      this.hideAfterXTimeout = null;
    }
    let _me = this;
    this.hideAfterXTimeout = setTimeout(() => {
      _me.hideControls();
    }, 5000);
    this.overlay.classList.remove("hide");
  }

  hideControls() {
    this.setState({
      visible: false
    });
    if (this.hideAfterXTimeout) {
      clearTimeout(this.hideAfterXTimeout);
      this.hideAfterXTimeout = null;
    }
    this.overlay.classList.add("hide");
  }

  cc(){
    console.log("clicked");
  }

  render() {
    return (
      <div ref={this.overlayRef.bind(this)} className="overlay hide">
      <div className="visibility">
        <div onClick={this.cc.bind(this)} data-video="control" className="controls">
          CC
        </div>
      </div>
      </div>
    );
  }
}


ReactDOM.render(<App />, document.getElementById('app'));

CSS:

.App {
  font-family: sans-serif;
  text-align: center;
}

.overlay {
  width: 720px;
  height: 405px;
  outline: 1px solid red;

  opacity: 1;
  visibility: visible;
  transition: 0.3s ease-out opacity;
}

.overlay.hide {
  opacity: 0;
}

.overlay.hide > .visibility {
  visibility: hidden;
}

.overlay > .visibility {
  visibility: visible;
}

.controls {
  width: 64px;
  height: 64px;
  outline: 1px solid blue;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM