我正在订阅click
元素上的button
事件。如果您点击按钮,这似乎在移动设备上起作用,但是如果将其按住一会儿然后释放它,则不会触发。至少这就是我最近使用Chrome的Android手机上的运行方式。
所以我想在释放按钮时触发一些操作。因此,我假设我不应该去touchstart
,因为它会在第一次按下按钮时触发。
preventDefault()
?我找到了这篇文章,但来自2013年:https://www.html5rocks.com/en/mobile/touchandmouse/
答案 0 :(得分:2)
经过一些尝试,似乎所有浏览器在这里的行为都不相同...
在Firefox和Android上的Chrome浏览器中,单击事件都被 contextmenu 事件丢弃,我还无法在Safari上进行测试。但是,在Firefox中,唯一会触发的事件是touchend
,而在Chrome上,有时会触发 touchcancel (显然是在选择按钮中的文本时)。
因此,您需要监听 touchend 事件,该事件与 mouseup 事件不同,如果您确实将光标移到元素外部后也会触发开始单击,但如果您先在外部单击并随后将光标移到该元素上,则不会触发,对于 touchcancel 事件,该事件可能会在用户释放该位置之前触发一点(但这是我们可以获得的最新活动...)。
现在,要避免同时触发 click 和 touchend / touchcancel 事件,您需要对事件处理程序进行反跳操作(即,强制事件处理程序在给定的时间间隔内仅运行一次),并且可能还防止 contextmenu 事件的默认行为。
// simple logs:
['click', 'touchstart', 'touchend', 'touchcancel', 'contextmenu'].forEach(type => {
btn.addEventListener(type, e => console.log(e.type));
});
// what you need:
btn.oncontextmenu = e => e.preventDefault(); // prevent the context menu on long touch
btn.onclick = btn.ontouchend = btn.ontouchcancel = debounce(e => {
console.log('Correctly handled the click event');
}, 100);
function debounce(fn, timeout=0) {
let flag = false;
return function() {
if (!flag) {
flag = true;
setTimeout(_ => flag = false, timeout);
fn.call(...arguments);
}
};
}
<button id="btn">
click me
</button>
请注意,即使单击按钮的默认操作也不会发生(例如,如果此按钮位于
答案 1 :(得分:1)
所以我尝试了一下,它似乎正常工作。它也会在单击鼠标,短按和长按时触发。由于问题是关于Chrome的,因此我在Android的Chrome 71.0.3578.99上进行了测试。
首先,您需要禁止用户在按钮上进行选择,否则,将不会长按。
第二,为什么每个人都非常关心释放鼠标/手指在其他地方?开始单击/轻击然后移开/滑动的唯一原因是用户改变了主意,并且不想执行按钮所执行的任何操作。
最后,在我的代码中,根据需要删除并添加了事件侦听器。这仅是由于问题的结构:此代码在台式机和移动设备上均可使用。在支持鼠标和触摸屏的设备上也不会中断。
回答要点的问题:
click
和touchstart
/ touchend
。touchend
,然后触发click
事件)。您可能希望假设触发一次触摸事件,那么用户没有鼠标连接到设备-在这种情况下,只需删除clickFunc()
之外的//Your code
的全部内容即可: 。
const button = document.getElementById("button");
function clickFunc(e){
if(e.touches){
e.preventDefault(); //Try to comment it out: double triggers on short tap
button.removeEventListener("touchend", clickFunc);
button.addEventListener("click", clickFunc);
console.log('tapped!');
}else{
console.log('clicked!');
}
//
//Your code here
}
function touchFunc(){
button.removeEventListener("click", clickFunc);
button.addEventListener("touchend", clickFunc);
}
window.onload=function(){
button.addEventListener("click", clickFunc);
button.addEventListener("touchstart", touchFunc);
}
#button{
user-select: none; /*find crossbrowser solution!*/
/*For testing purposes*/
margin-top: 100px;
margin-left: 100px;
font-size: 48px;
padding: 10px 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Clicks and Touches</title>
</head>
<body>
<button id="button">Click me!</button>
</body>
</html>
答案 2 :(得分:0)
处理触摸和鼠标单击而无需两次触发:
function handleInteraction(evt) {
evt.preventDefault()
console.log('interacted')
// your code...
}
var el = document.getElementById('el');
el.addEventListener('touchstart', handleInteraction)
el.addEventListener('click', handleInteraction)
#el {
cursor: pointer;
width: 100px;
height: 100px;
background-color: #bcd1ea;
text-align: center;
line-height: 100px;
color: #246dad;
}
<div id='el'>
el
</div>