因此,我在为 Microsoft Surface 开发 Web 应用程序时遇到了一个有趣的问题。
我想为用户与 DOM 元素交互时添加事件侦听器。现在我可以这样做:
if ('ontouchstart' in document.documentElement) {
//Attach code for touch event listeners
document.addEventListener("touchstart" myFunc, false);
} else {
//Attach code for mouse event listeners
document.addEventListener("mousedown" myFunc, false);
}
如果设备没有鼠标输入,这个问题会很简单,上面的代码也可以正常工作。但是 Surface(以及许多新的 Windows 8 计算机)同时具有触摸和鼠标输入。所以上面的代码只有在用户触摸设备时才有效。鼠标事件监听器永远不会被附加。
所以我想,好吧,我可以这样做:
if ('ontouchstart' in document.documentElement) {
//Attach code for touch event listeners
document.addEventListener("touchstart" myFunc, false);
}
//Always attach code for mouse event listeners
document.addEventListener("mousedown" myFunc, false);
不支持触摸的设备不会附加事件,但使用触摸的设备将注册其处理程序。但是,问题在于myFunc()
它将在触摸设备上被调用两次:
myFunc()
当“touchstart”被提升时将触发- 因为触摸浏览器通常会经历循环touchstart -> touchmove -> touchend -> mousedown -> mousemove -> mouseup -> click,
myFunc()
将在“mousedown”中再次调用
我考虑过添加代码以myFunc()
使其调用e.preventDefault()
,但这似乎也会阻止touchend以及某些浏览器上的mousedown / mousemove / mouseup (链接)。
我讨厌做用户代理嗅探器,但似乎触摸浏览器在触摸事件的实现方式上有所不同。
我一定遗漏了一些东西,因为似乎这些 JavaScript 实现肯定是在浏览器同时支持鼠标和触摸的情况下决定的!