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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14406161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 21:33:05  来源:igfitidea点击:

Listening to mousedown AND touchstart on devices that use touch and a mouse (e.g. Surface)

javascriptwindows-8touch

提问by userx

So, I've run across an interesting problem while working on a Web application for the Microsoft Surface.

因此,我在为 Microsoft Surface 开发 Web 应用程序时遇到了一个有趣的问题。

I want to add event listeners for when a user interacts with a DOM element. Now I can do:

我想为用户与 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);
}

If the device didn't have a mouse input, this problem would be simple and the above code would work just fine. But the Surface (and many new Windows 8 computers) have BOTH a touch and mouse input. So the above code would only work when the user touched the device. The mouse event listeners would never be attached.

如果设备没有鼠标输入,这个问题会很简单,上面的代码就可以正常工作。但是 Surface(以及许多新的 Windows 8 计算机)同时具有触摸和鼠标输入。所以上面的代码只有在用户触摸设备时才有效。永远不会附加鼠标事件侦听器。

So then I thought, well, I could do this:

然后我想,好吧,我可以这样做:

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);

Devices that don't support touch wouldn't have the events attached, but a device that uses touch will register its handlers. The problem with this though is that myFunc()will be called twice on a touch device:

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

  1. myFunc()will fire when "touchstart" is raised
  2. Because touch browsers typically go through the cycle touchstart-> touchmove-> touchend-> mousedown-> mousemove-> mouseup-> click, myFunc()will be called again in "mousedown"
  1. myFunc()当“touchstart”被提升时会触发
  2. 因为触摸浏览器通常会经过循环touchstart-> touchmove-> touchend-> mousedown-> mousemove-> mouseup-> clickmyFunc()将在“mousedown”中再次调用

I've considered adding code tomyFunc()such that it calls e.preventDefault()but this seems to also block touchendas well as mousedown/ mousemove/ mouseupon some browsers (link).

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

I hate doing useragent sniffers, but it seems as if touch browsers have variations in how touch events are implemented.

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

I must be missing something because it seems that surely these JavaScript implementations were decided with possibility of a browser supporting both a mouse and touch!

我一定遗漏了一些东西,因为这些 JavaScript 实现似乎肯定是由浏览器支持鼠标和触摸的可能性决定的!

回答by Cheshire

For windows 8 you can use the "MSPointerDown " event.

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

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

Also add the following to your style:

还将以下内容添加到您的样式中:

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

See http://msdn.microsoft.com/en-us/library/ie/hh673557(v=vs.85).aspxfor more info.

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

回答by noypiscripter

Inside myFunc, check the event type. If it's touchstart, then do e.stopPropagation().

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

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

回答by curly_brackets

EDITED:If you use jQuery, you will be able to do like this:

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

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

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

This will fire only one of the bind's event.

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

Found here: How to bind 'touchstart' and 'click' events but not respond to both?

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