12

因此,我在为 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 -> clickmyFunc()将在“mousedown”中再次调用

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

我讨厌做用户代理嗅探器,但似乎触摸浏览器在触摸事件的实现方式上有所不同。

我一定遗漏了一些东西,因为似乎这些 JavaScript 实现肯定是在浏览器同时支持鼠标和触摸的情况下决定的!

4

3 回答 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

于 2013-07-24T12:45:17.937 回答
-1

在 myFunc 中,检查事件类型。如果是 touchstart,那就做e.stopPropagation().

function myFunc(e) {
    if (e.type === 'touchstart') {
        e.stopPropagation();
    }
    //the rest of your code here
}
于 2013-07-11T20:54:32.247 回答
-3

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

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

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

这只会触发绑定事件之一。

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

于 2013-01-28T10:21:00.413 回答