监听使用触摸和鼠标的设备(例如Surface)上mousedown和touchstart事件。

14

所以,在为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. 当 "touchstart" 被触发时,myFunc() 会触发
  2. 由于触摸浏览器通常遵循循环 touchstart -> touchmove -> touchend -> mousedown -> mousemove -> mouseup -> clickmyFunc() 将在 "mousedown" 中再次被调用。

我考虑过向myFunc()添加代码,使其调用 e.preventDefault(),但这似乎也会在一些浏览器(链接)上阻止 touchend 以及 mousedown / mousemove / mouseup

我不喜欢做用户代理嗅探器,但似乎触摸浏览器在实现触摸事件方面存在差异。

我一定是漏了什么,因为这些 JavaScript 实现似乎肯定考虑了浏览器支持鼠标和触摸的可能性!


考虑到Surface并不支持安卓系统,这与安卓有什么关系呢? - CommonsWare
@CommonsWare - 我的问题与所有支持鼠标的触摸设备相关,因此似乎适用于Windows 8和Android。 - userx
是的,ChromeOS怎么样? - Chris Love
已经过去2个月了,你有什么发现吗? - jedmao
9
这不是一个重复的问题,它与“How to bind 'touchstart' and 'click' events but not respond to both?”不同,那是一个特定于jQuery的问题,有着针对jQuery的答案。 - Frederik Krautwald
3个回答

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,了解更多信息。

可能禁用滚动 - Walle Cyril

-1
在 myFunc 函数内部,检查事件类型。如果是 touchstart,则执行 e.stopPropagation()
function myFunc(e) {
    if (e.type === 'touchstart') {
        e.stopPropagation();
    }
    //the rest of your code here
}

很不幸,这也行不通,因为它可能是 Windows 8 笔记本电脑上的“mousedown”事件,该笔记本电脑同时具有鼠标和触摸屏。 - userx
这会导致触摸设备无法触发点击事件。 - OG Sean

-3

1
这并没有解决问题。它只是为两个事件附加了处理程序,因此我不相信它可以防止两个事件都触发(从而导致附加的函数执行两次)。 - userx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接