所以,在为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()
将被调用两次:
- 当 "touchstart" 被触发时,
myFunc()
会触发 - 由于触摸浏览器通常遵循循环 touchstart -> touchmove -> touchend -> mousedown -> mousemove -> mouseup -> click,
myFunc()
将在 "mousedown" 中再次被调用。
我考虑过向myFunc()
添加代码,使其调用 e.preventDefault()
,但这似乎也会在一些浏览器(链接)上阻止 touchend 以及 mousedown / mousemove / mouseup。
我不喜欢做用户代理嗅探器,但似乎触摸浏览器在实现触摸事件方面存在差异。
我一定是漏了什么,因为这些 JavaScript 实现似乎肯定考虑了浏览器支持鼠标和触摸的可能性!