簡體   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