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

时间:2013-01-18 19:25:57

标签: javascript windows-8 touch

因此,我在处理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()将在触摸设备上调用两次:

  1. myFunc()会在“touchstart”被提升时触发
  2. 因为触摸浏览器通常会经历 touchstart - >周期。 touchmove - > touchend - > mousedown - > mousemove - > mouseup - > 点击,将在“mousedown”
  3. 中再次调用myFunc()

    我已考虑将代码添加到myFunc(),以便调用e.preventDefault(),但这似乎也会阻止 touchend 以及 mousedown /某些浏览器上的 mousemove / mouseup link)。

    我讨厌使用有吸引力的嗅探器,但似乎触摸浏览器在触摸事件的实现方式上存在差异。

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

3 个答案:

答案 0 :(得分:2)

对于Windows 8,您可以使用“MSPointerDown”事件。

 if (window.navigator.msPointerEnabled) {
     document.addEventListener("MSPointerDown" myFunc, false);
 }

还要在您的样式中添加以下内容:

  html { 
    -ms-touch-action: none; /* Direct all pointer events to JavaScript code. */
  }

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspx

答案 1 :(得分:0)

在myFunc中,检查事件类型。如果是touchstart,请执行e.stopPropagation()

function myFunc(e) {
    if (e.type === 'touchstart') {
        e.stopPropagation();
    }
    //the rest of your code here
}

答案 2 :(得分:-3)

<强>编辑: 如果您使用jQuery,则可以这样做:

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

$("a").bind(clickEventType, function() {
    //Do something
});

这将仅触发绑定事件中的一个。

在此处找到:How to bind 'touchstart' and 'click' events but not respond to both?