如何检测 JavaScript 中的设备触摸支持?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14439903/
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-08-24 16:45:58  来源:igfitidea点击:

How can I detect device touch support in JavaScript?

javascriptgoogle-chromejavascript-events

提问by BenM

In the past, when detecting whether a device supports touch events in JavaScript, we could do something like this:

过去,在 JavaScript 中检测设备是否支持触摸事件时,我们可以这样做:

var touch_capable = ('ontouchstart' in document.documentElement);

However, Google Chrome (17.x.x+) returns truefor the above check, even if the underlying device does not support touch events. For example, running the above code on Windows 7 returns true, and thus if we combine it with something like:

但是,true即使底层设备不支持触摸事件,Google Chrome (17.x.x+) 也会返回进行上述检查。例如,在 Windows 7 上运行上面的代码返回 true,因此如果我们将它与类似的东西结合起来:

var start_evt = (touch_capable) ? 'ontouchstart' : 'onmousedown';

On Google Chrome, the event is never fired since we're binding to ontouchstart. In short, does anyone know a reliable way to circumvent this? I am currently running the following check:

在 Google Chrome 上,由于我们绑定到ontouchstart. 简而言之,有没有人知道一种可靠的方法来规避这种情况?我目前正在运行以下检查:

var touch_capable = ('ontouchstart' in document.documentElement && navigator.userAgent.toLowerCase().indexOf('chrome') == -1)

Which is far from ideal...

这远非理想......

采纳答案by Alnitak

The correct answer is to handle bothevent types - they're not mutually exclusive.

正确的答案是处理这两种事件类型——它们不是相互排斥的。

For a more reliable test for touch support, also look for window.DocumentTouch && document instanceof DocumentTouchwhich is one of the tests used by Modernizr

要获得更可靠的触摸支持测试,请同时查找Modernizrwindow.DocumentTouch && document instanceof DocumentTouch使用的测试之一

Better yet, just use Modernizr yourself and have it do the feature detection for you.

更好的是,只需自己使用 Modernizr 并让它为您进行特征检测。

Note though that you cannot prevent false positives, hence my first line above - you've gotto support both.

但是请注意,你不能防止误报,因此我上面第一行-你已经得到了支持两种。

回答by Benson

This is a modification of how Modernizr performs touch detection, with added support to work with IE10+ touch devices.

这是对 Modernizr 执行触摸检测方式的修改,增加了对 IE10+ 触摸设备的支持。

var isTouchCapable = 'ontouchstart' in window ||
 window.DocumentTouch && document instanceof window.DocumentTouch ||
 navigator.maxTouchPoints > 0 ||
 window.navigator.msMaxTouchPoints > 0;

It's not foolproof since detecting a touch device is apparently an impossibility.

这不是万无一失的,因为检测触摸设备显然是不可能的

Your mileage may vary:

你的旅费可能会改变:

  • Older touchscreen devices only emulate mouse events
  • Some browsers & OS setups may enable touch APIs when no touchscreen is connected
  • In a hybrid mouse/touch/trackpad/pen/keyboard environment, this doesn't indicate which input is being used, only that the browser is touchy--it only detects if the browser couldaccept or emulate a touch input. For example, a user could switch from using a mouse to touching the screen on a touch-enabled laptop or mouse-connected tablet at any moment.
  • 较旧的触摸屏设备仅模拟鼠标事件
  • 当没有连接触摸屏时,某些浏览器和操作系统设置可能会启用触摸 API
  • 在混合鼠标/触摸/触控板/笔/键盘环境中,这并不表示正在使用哪个输入,仅表示浏览器是敏感的——它只检测浏览器是否可以接受或模拟触摸输入。例如,用户可以随时从使用鼠标切换到触摸支持触摸的笔记本电脑或连接鼠标的平板电脑上的屏幕。

Update:A tip: Do not use touch-capability detection to control & specify UI behaviors, use event listeners instead. Design for the click/touch/keyup event, not the device, touch-capability detection is typically used to save the cpu/memory expense of adding an event listener. One example of where touch detection could be useful and appropriate:

更新:提示:不要使用触摸功能检测来控制和指定 UI 行为,而是使用事件侦听器。为 click/touch/keyup 事件而不是设备设计,触摸功能检测通常用于节省添加事件侦听器的 CPU/内存开销。触摸检测可能有用且合适的一个示例:

if (isTouchCapable) {
    document.addEventListener('touchstart', myTouchFunction, false); 
}

回答by techfoobar

You should consider using the well tested (and cross-browser) Modernizr's touch test.

您应该考虑使用经过充分测试(和跨浏览器)的 Modernizr 触摸测试。

From their site:

从他们的网站:

// bind to mouse events in any case

if (Modernizr.touch){
   // bind to touchstart, touchmove, etc and watch `event.streamId`
} 

http://modernizr.github.com/Modernizr/touch.html

http://modernizr.github.com/Modernizr/touch.html

回答by Soren

Well old question, but having to do this without a library, I created the following solution -- simply let the events talk for them self -- when you see the touchevents, just disable the processing of the mouseevents.

很好的老问题,但是必须在没有库的情况下执行此操作,我创建了以下解决方案 - 只需让事件为它们自己说话 - 当您看到touch事件时,只需禁用mouse事件处理即可。

In coffescript is would look like this;

在 coffescript 中是这样的;

           hasTouch = false
           mouseIsDown = false
           @divs.on "touchstart", (e)->
              hasTouch = true
              touchstart(e.timeStamp,e.originalEvent.touches[0].pageX);
              return true
           @divs.on "mousedown", (e)->
              mouseIsDown = true;
              touchstart(e.timeStamp,e.clientX) if not hasTouch
              return true

           @divs.on 'touchmove', (e) ->
              touchmove(e.timeStamp,e.originalEvent.touches[0].pageX);
              return true;
           @divs.on 'mousemove', (e) ->
              touchmove(e.timeStamp,e.clientX) if mouseIsDown and not hasTouch 
              return true;

           @divs.on 'touchend', (e) ->
              touchend();
              return true
           @divs.on 'mouseup', (e) ->
              mouseIsDown = false;
              touchend() if not hasTouch
              return true

The just define functions for touchstart,moveand endcontaining the actual logic....

只是为 定义函数touchstartmoveend包含实际的逻辑......