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

时间:2013-01-21 13:38:01

标签: javascript google-chrome javascript-events

过去,当检测设备是否支持JavaScript中的触摸事件时,我们可以执行以下操作:

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

但是,即使底层设备不支持触摸事件,Google Chrome(17.x.x +)也会返回true进行上述检查。例如,在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 个答案:

答案 0 :(得分:12)

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

要获得更可靠的触摸支持测试,还要查找window.DocumentTouch && document instanceof DocumentTouch <{1}}所使用的测试之一{{1}}

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

请注意,虽然你无法阻止误报,因此我的第一行 - 你已经 来支持两者。

答案 1 :(得分:6)

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

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

detecting a touch device is apparently an impossibility以后并非万无一失。

您的里程可能会有所不同:

  • 较旧的触摸屏设备仅模拟鼠标事件
  • 一些浏览器&amp;操作系统设置可在未连接触摸屏时启用触摸API
  • 在混合鼠标/触控/触控板/笔/键盘环境中,这并不表示哪个输入正在使用,只是浏览器是 touchy - 它仅检测浏览器是否接受或模拟触摸输入。例如,用户可以随时从使用鼠标切换到触摸笔记本电脑或鼠标连接的平板电脑上的屏幕。

<强>更新 提示:不要使用触摸功能检测来控制&amp;指定UI行为use event listeners instead。点击/触摸/键盘事件的设计,而不是设备,触摸功能检测通常用于节省添加事件监听器的CPU /内存费用。触摸检测可能有用且适当的一个例子:

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

答案 2 :(得分:0)

您应该考虑使用经过良好测试(和跨浏览器)的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

答案 3 :(得分: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的函数....