更新:
我一直在研究如何实现同时使用点击和触摸结束事件来执行同一个函数,而且如果类型发生变化,该函数会有效地阻止事件。我的目标是拥有更具响应性的应用程序界面 - 我想减少事件开始到 UI 反馈循环的时间。
为了使这个实现工作,假设您已经将所有相关事件添加到“click”和“touchend”上。这可以防止一个元素被剥夺事件冒泡,如果两个事件都需要运行,但是它们的类型不同。
这里是一个基于轻量级 API 的实现,我已经简化了演示目的。它演示了如何在折叠元素上使用功能。
var tv = {
eventValidator: function(e, element, callback, context, args){
if(element && element.type && element.type !== e.type){
e.stopPropagation();
e.preventDefault();
return tv.createEventCacheObj({}, true);
} else {
element = tv.createEventCacheObj(e);
(typeof context === "object" ? callback.apply(context, args) : callback());
return element;
}
},
createEventCacheObj: function (event, reset){
if(typeof reset !== 'boolean') reset = false;
return {
type: !reset ? event.type : null,
time: !reset ? (event.timeStamp).toFixed(2): null
};
}
};
var eventCache = [];
var pos = 0;
var $collapses = document.getElementsByClassName('tv-collapse__heading');
Array.prototype.forEach.call($collapses, function(ele){
ele.addEventListener('click', toggleCollapse);
ele.addEventListener('touchend', toggleCollapse);
ele.setAttribute('data-event-cache', String(pos++));
});
function toggleCollapse(e){
eventCache[pos] = tv.eventValidator(e, eventCache[pos], function(){
}, this, arguments);
}
这是一个修改自
Rafael Fragoso答案的响应 - 纯JS。
(function(){
button = document.getElementById('sayHi');
button.addEventListener('touchstart', ohHai);
button.addEventListener('click', ohHai);
function ohHai(event){
event.stopPropagation();
event.preventDefault();
console.log('ohHai is:', event.type);
};
})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SO - Answer</title>
</head>
<body>
<button id="sayHi">Anyone there?</button>
</body>
</html>
在以下内容上运行片段并注意输出:
- 手机
- 平板电脑
- 平板电脑(桌面模式-如果适用)
- 台式电脑
- 台式电脑(触摸屏-如果适用)
关键是我们阻止连续事件的触发。移动浏览器尽力模拟点击,当触摸发生时。我希望我能找到一篇文章的链接,它解释了所有在touchstart到click之间发生的事件。(实际上我正在寻找双击和单击之间300ms延迟的原因)。
触摸和鼠标设备
我使用Surface Pro和Windows 10桌面电脑进行了几次测试。我发现它们都会触发事件,就像你预期的那样,对于触摸是touchstart,对于触控板、鼠标和笔是click。有趣的是,一个接近但不在按钮上的触摸事件会触发一个没有触摸事件的点击事件。似乎Windows 10中内置的功能会在半径范围内查找最近的节点,如果找到一个节点,它将触发基于鼠标的事件。
相同类型的多个事件
如果一个元素上有两个相同类型的事件,阻止事件冒泡可能会防止其中一个事件触发。有几种不同的方法可以使用某种缓存来处理这个问题。我的初步想法是修改事件对象,但我们只获得了一个引用,所以我认为缓存解决方案将不得不足够。
.bind('touchstart mouseup')
可以解决这个问题(基于下面的评论之一) - oriadam.one
方法:http://api.jquery.com/one。 - oriadam