16

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

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

true但是,即使底层设备不支持触摸事件,Google Chrome (17.x.x+) 也会返回上述检查。例如,在 Windows 7 上运行上述代码会返回 true,因此如果我们将其与以下内容结合使用:

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

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

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

这远非理想...

4

4 回答 4

15

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

要获得更可靠的触控支持测试,还请查看Modernizrwindow.DocumentTouch && document instanceof DocumentTouch使用的测试之一

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

请注意,尽管您无法防止误报,因此我上面的第一行 - 您必须同时支持两者。

于 2013-01-21T13:38:56.613 回答
11

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

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

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

你的旅费可能会改变:

  • 较旧的触摸屏设备仅模拟鼠标事件
  • 某些浏览器和操作系统设置可能会在未连接触摸屏时启用触摸 API,例如,在安装了触摸屏驱动程序但触摸硬件不起作用或未安装的系统中。
  • 在混合鼠标/触摸/触控板/笔/键盘环境中,这并不表示正在使用哪个输入,只是浏览器检测到存在触摸硬件。例如,用户可以随时从使用鼠标切换到触摸支持触摸的笔记本电脑或连接鼠标的平板电脑上的屏幕。它只检测浏览器是否认为它可以接受或模拟触摸输入,例如,在 Chrome 开发工具中使用移动模拟模式时。

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

if (isTouchCapable) {
    document.addEventListener('touchstart', myTouchFunction, false); 
}
于 2015-12-08T01:05:46.663 回答
1

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

从他们的网站:

// 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

于 2013-01-21T13:41:52.517 回答
0

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

在 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

刚刚定义的函数touchstartmoveend包含实际的逻辑....

于 2015-09-26T16:09:21.340 回答