在使用触摸和鼠标的设备上聆听mousedown和touchstart(例如Surface)

use*_*erx 12 javascript touch windows-8

因此,我在处理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);
}
Run Code Online (Sandbox Code Playgroud)

如果设备没有鼠标输入,这个问题很简单,上面的代码就可以了.但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);
Run Code Online (Sandbox Code Playgroud)

不支持触摸的设备不会附加事件,但使用触摸的设备将注册其处理程序.但问题是myFunc()在触摸设备上会被调用两次:

  1. myFunc() 当"touchstart"被提出时会触发
  2. 因为触摸浏览器通常会经历循环touchstart - > touchmove - > touchend - > mousedown - > mousemove - > mouseup - > click,myFunc()将在"mousedown"中再次调用

我已经考虑过添加代码以便myFunc()它调用e.preventDefault()但是这似乎也阻止了某些浏览器(链接)上的touchend以及mousedown/mousemove/mouseup.

我讨厌使用useragent嗅探器,但似乎触摸浏览器在触摸事件的实现方式上有变化.

我必须遗漏一些东西,因为看起来肯定这些JavaScript实现决定了浏览器支持鼠标和触摸的可能性!

cur*_*ets -3

编辑: 如果您使用jQuery,您将能够这样做:

var clickEventType=((document.ontouchstart!==null)?'mousedown':'touchstart');

$("a").bind(clickEventType, function() {
    //Do something
});
Run Code Online (Sandbox Code Playgroud)

这将仅触发绑定事件之一。

在这里找到:如何绑定“touchstart”和“click”事件但不响应两者?