简体   繁体   English

防止触发文档事件侦听器?

[英]Prevent document event listener from firing?

I have document.addEventListener('touchstart', this.onDocument);我有document.addEventListener('touchstart', this.onDocument); so I can detect when a user clicks off something.所以我可以检测到用户何时点击了某些东西。

But on my button click handler I have:但是在我的按钮单击处理程序上,我有:

toggleItemActive(e) {
        e.stopPropagation();
        ....

But when I click the button on my iPad, the document touch handler still runs.但是当我单击 iPad 上的按钮时,文档触摸处理程序仍在运行。

How can I allow for clicks on my button without running the document touch handler?如何在不运行文档触摸处理程序的情况下允许点击我的按钮?

You can use Event#preventDefault but you need to also check the Event#defaultPrevented flag in the container if you do.您可以使用Event#preventDefault但如果您这样做,您还需要检查容器中的Event#defaultPrevented标志。

Example Using Event#defaultPrevented使用Event#defaultPrevented示例

 document.addEventListener("click", function(event) { if (event.defaultPrevented) return; console.log("Container Clicked"); }); document.querySelector("#test").addEventListener("click", function(event) { event.preventDefault(); console.log("Test Clicked"); });
 <button id="test">Test</button>

Example without Event#defaultPrevented没有Event#defaultPrevented示例

 document.addEventListener("click", function(event) { console.log("Container Clicked"); }); document.querySelector("#test").addEventListener("click", function(event) { event.preventDefault(); console.log("Test Clicked"); });
 <button id="test">Test</button>

Example Using Event#defaultPrevented ( touchstart event)使用Event#defaultPrevented示例( touchstart事件)

 document.addEventListener("touchstart", function(event) { if (event.defaultPrevented) return; console.log("Container Clicked"); }); document.querySelector("#test").addEventListener("touchstart", function(event) { event.preventDefault(); console.log("Test Clicked"); }); var event = document.createEvent("HTMLEvents"); event.initEvent("touchstart", true, true); document.querySelector("#test").dispatchEvent(event);
 <button id="test">Test</button>

Example that uses both click and touchstart listener使用clicktouchstart侦听器的示例

 document.addEventListener("touchstart", function(event) { if (event.defaultPrevented) return; console.log("Container Clicked"); }); document.querySelector("#test").addEventListener("touchstart", function(event) { event.preventDefault(); }); document.querySelector("#test").addEventListener("click", function(event) { console.log("Test Clicked"); });
 <button id="test">Test</button>

Example using ignored array使用忽略数组的示例

 var excludedList = ["test"]; document.addEventListener("touchstart", function(event) { if (excludedList.indexOf(event.target.id) !== -1) return; console.log("Container Clicked"); }); document.querySelector("#test").addEventListener("click", function(event) { console.log("Test Clicked"); }); var event = document.createEvent("HTMLEvents"); event.initEvent("touchstart", true, true); document.querySelector("#test").dispatchEvent(event);
 <button id="test">Test</button>

In the this.onDocument handler, check whether event.currentTarget is the button you want to prevent and do nothing.this.onDocument处理程序中,检查event.currentTarget是否是您要阻止的按钮并且什么也不做。 Some thing like this should work像这样的事情应该工作

onDocument(e){
  // get access to the target button e.g assuming your button has an id targetButton
  let targetButton = document.querySelector('#targetButton')

  // do no thing if the target button is clicked
  if(e.currentTarget === targetButton){
    return;
  }

  // do whatever you want to do
}

The problem is touchstart fires before click so you can never know in advance if the touch resolves into a click (it will always fire).问题是touchstartclick之前触发,所以你永远无法提前知道触摸是否解析为点击(它总是会触发)。

The easiest way to 'fix' your problem is to check in your touchStart event handler what you are dealing with. “解决”问题的最简单方法是检查您正在处理的 touchStart 事件处理程序。

function onDocumentTouchStart(e){
  if (!e.target.matches('button|a.this-one')) { // refine queryString for exclusions
    // proceed with logging
  }
}

Or briefly detach the touchstart event handler when clicking the button.或者在单击按钮时短暂分离 touchstart 事件处理程序。 This works but since it uses an async re-attachement it feels a bit dirty.这有效,但由于它使用异步重新附加,因此感觉有点脏。

 const onDocumentTouchStart = ()=>console.log('touchstart') toggleDocumentTouchStart(true) const button = document.querySelector('button') button.addEventListener('touchstart', e => { toggleDocumentTouchStart(false) requestAnimationFrame(toggleDocumentTouchStart.bind(null,true)) }) button.addEventListener('click', ()=>console.log('buttonClick')) function toggleDocumentTouchStart(add){ add ?document.body.addEventListener('touchstart', onDocumentTouchStart) :document.body.removeEventListener('touchstart', onDocumentTouchStart) }
 <button>button that prevents</button> <div>foo</div> <button>another button</button>

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

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