我有document.addEventListener('touchstart', this.onDocument);
,因此我可以检测到用户何时单击某些内容。
但是在我的按钮单击处理程序上,我有:
toggleItemActive(e) {
e.stopPropagation();
....
但是当我单击iPad上的按钮时,文档触摸处理程序仍然运行。
如何在不运行文档触摸处理程序的情况下允许单击按钮?
答案 0 :(得分:1)
您可以使用Event#preventDefault
,但如果需要,还需要检查容器中的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>
不带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>
使用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>
同时使用click
和touchstart
侦听器的示例
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>
使用忽略数组的示例
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>
答案 1 :(得分:0)
在this.onDocument
处理程序中,检查event.currentTarget
是否是您要防止的按钮,并且什么也不做。
这样的事情应该可以工作
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
}
答案 2 :(得分:0)
问题是touchstart
在click
之前触发,因此您永远无法事先知道触摸是否会分解为点击(它将始终触发)。
“解决”问题的最简单方法是在touchStart事件处理程序中检查要处理的内容。
function onDocumentTouchStart(e){
if (!e.target.matches('button|a.this-one')) { // refine queryString for exclusions
// proceed with logging
}
}
或在单击按钮时短暂分离touchstart事件处理程序。这行得通,但是由于它使用了异步重新连接,因此感觉有点脏。
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>