使用Javascript检测触摸屏设备

131

在JavaScript/jQuery中,如何检测客户端设备是否有鼠标?

我有一个网站,在用户将鼠标悬停在某个项目上时会弹出一些信息面板。我正在使用jQuery.hoverIntent来检测悬停事件,但是这显然不适用于像iPhone/iPad/Android这样的触摸屏设备。因此,在这些设备上,我想改为使用轻触来显示信息面板。


6
为什么不能两者兼顾?在非触摸屏设备中,触控板功能不可取吗? - EMPraptor
1
由于一些新设备不支持:hover,因此在为多个设备编写一个样式表时,最好仅将:hover用于纯粹的美观目的。 - drudge
@empraptor:说得好 - 是的,我可以这样做。但是...我们也考虑在触摸屏设备上始终显示面板 - 在这种情况下,我需要能够检测支持。 - Brad Robinson
如果您可以在触摸屏设备上始终显示面板,那么您也可以在其他设备上显示它吗?面板有多大,为什么只在悬停/轻敲时显示它是可取的? - EMPraptor
16个回答

268
var isTouchDevice = 'ontouchstart' in document.documentElement;

注意:仅仅因为设备支持触摸事件并不意味着它是一个纯触摸屏幕设备。许多设备(例如我的Asus Zenbook)支持单击和触摸事件,即使它们没有任何实际的触摸输入机制。在设计触摸支持时,始终包括单击事件支持,并且永远不要假设任何设备是纯粹的其中之一。


34
如Modernizr文档所述,这只能检测浏览器能力,而不能检测设备能力... 在没有触摸输入并运行支持触摸的浏览器的设备上,您将得到一个错误的正面结果。我不知道有没有本地检测设备触摸能力的方法,除非等待触摸事件发生。 - Stu Cox
12
为了检测IE 10触摸事件,我使用以下代码:(window.navigator.msMaxTouchPoints || ('ontouchstart' in document.documentElement))。 - Alexander Kellett
2
在 BlackBerry 9300 上,'ontouchstart' in document.documentElement 不正确地返回 true。 - Simpler
10
如果软件(Win 8、现代浏览器)支持触摸,那么即使您使用不支持触摸的硬件(桌面、标准显示器、鼠标和键盘),这也将始终成立。因此,这个解决方案已经过时了。 - Barney
1
有趣的是,它不是驼峰命名法,因为 JavaScript 中普遍使用驼峰命名法。我的意思是现在人们需要复制、粘贴和编辑代码... :) - Ross
显示剩余4条评论

20

这段代码可以检测触摸屏幕,但要小心,因为对于带有触摸屏的笔记本电脑也会返回TRUE。如果您想区分用户是来自手机/平板还是计算机/笔记本电脑,这可能会成为一个问题,因为对于带有触摸屏的笔记本电脑它会返回TRUE。 - Combine

12
+1 针对 hoverclick 都进行处理。另一种方法是使用 CSS 媒体查询,在较小的屏幕或移动设备上仅使用某些样式,这些设备最有可能具有触摸/点击功能。因此,如果您在 CSS 中有某些特定样式,并且从 jQuery 中检查这些元素是否具有移动设备样式属性,则可以钩入它们以编写针对移动设备的代码。
请参见: http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

1
好的解决方案,你可以尝试使用hover检查和one()绑定来实现,这样它只会在第一次触发时执行。 - Timothy Perez
问题在于,如果您按屏幕宽度进行定位,则当您旋转设备时(以 iPhone 6+ 736x414 为例),它将不具有相同的样式。因此,这不是最佳解决方案 :/ - antoni

10
if ("ontouchstart" in window || navigator.msMaxTouchPoints) {
    isTouch = true;
} else {
    isTouch = false;
}

可以在任何地方使用!


那跟鼠标有什么关系呢?(实际问题) - hexalys
2
更简单的方法是执行 isTouch = "ontouchstart" in window || navigator.msMaxTouchPoints; - Andrew

8
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

为什么要使用maxTouchPoints和msMaxTouchPoints:

微软已经声明,从Internet Explorer 11开始, 微软供应商前缀版本的此属性(msMaxTouchPoints) 可能会被删除,并建议改用maxTouchPoints。

来源:http://ctrlq.org/code/19616-detect-touch-screen-javascript


这在谷歌浏览器开发者工具中模拟设备中运行良好,谢谢。 - Behnam

4

我使用:

if(jQuery.support.touch){
    alert('Touch enabled');
}

在jQuery Mobile 1.0.1中


2
jQuery建议使用Modernizr(http://modernizr.com/)代替jQuery.support:参考 - http://api.jquery.com/jQuery.support/ - - Jonathan Marzullo

4

对于我的第一篇帖子/评论:

我们都知道'touchstart'在点击之前触发。

我们也知道当用户打开您的页面时,他或她会执行以下操作:

  1. 移动鼠标
  2. 点击
  3. 触摸屏幕(用于滚动等)

让我们尝试一些东西:

//--> 开始:jQuery

var hasTouchCapabilities = 'ontouchstart' in window && (navigator.maxTouchPoints || navigator.msMaxTouchPoints);
var isTouchDevice = hasTouchCapabilities ? 'maybe':'nope';

//attach a once called event handler to window

$(window).one('touchstart mousemove click',function(e){

    if ( isTouchDevice === 'maybe' && e.type === 'touchstart' )
        isTouchDevice = 'yes';
});

//<-- 结束: jQuery

祝您拥有愉快的一天!


4

谷歌浏览器似乎在这方面返回了虚假的正面结果:

var isTouch = 'ontouchstart' in document.documentElement;

我想这与它的“模拟触摸事件”的能力有关(F12->右下角的设置->“覆盖”选项卡->最后一个复选框)。我知道默认情况下它是关闭的,但这就是我认为导致结果变化的原因(在Chrome中,“in”方法曾经起作用)。 然而,据我测试,这似乎是有效的:

var isTouch = !!("undefined" != typeof document.documentElement.ontouchstart);

我运行了这段代码的所有浏览器都显示typeof为"object",但是我更加确定它不是undefined :-)

在IE7、IE8、IE9、IE10、Chrome 23.0.1271.64、iPad上的Chrome 21.0.1180.80和iPad Safari上进行了测试。如果有人进行更多的测试并分享结果,那就太棒了。


这两种方法在Win 8 PC上与FF 23和Chrome 28一起使用会出现错误的结果。这是一直如此还是因为我曾经连接过一个触摸屏到这台电脑 - 可能是在安装FF和Chrome之前 - 但现在已经拆除了?我没有设置“模拟触摸事件”选项。 - user2373682
哦,新硬件总是让人头疼。浏览器必须与操作系统抽象层一起工作...但并不总是实现所有功能...简而言之,使用JS时必须依赖于浏览器 :) 永远没有通用的方法。 - Boyan
这两个在非触摸笔记本上的Ubuntu Firefox上返回true。 - NoBugs

4

我为我的网站之一撰写了这篇文章,它可能是最可靠的解决方案。特别是因为即使是 Modernizr 也可能会在触摸检测上出现误报。

如果你正在使用 jQuery

$(window).one({
  mouseover : function(){
    Modernizr.touch = false; // Add this line if you have Modernizr
    $('html').removeClass('touch').addClass('mouse');
  } 
});

或者仅使用纯JS...
window.onmouseover = function(){ 
    window.onmouseover = null;
    document.getElementsByTagName("html")[0].className += " mouse";
}

4
请注意:至少iPad也会触发onmouseovers。 - Joril
使用 Windows 平板电脑上的 IE 浏览器的用户可能希望同时使用触摸和鼠标。 - Sebazzz
这篇文章是在Windows平板电脑出现之前发布的。 - Timothy Perez
@s427 - 该死的IE...只需检查IE8即可。我认为没有任何移动设备使用<= IE8。 - Timothy Perez

3
我在讨论中测试了上述代码。
 function is_touch_device() {
    return !!('ontouchstart' in window);
 }

可以在安卓的Mozilla、Chrome、Opera、安卓默认浏览器以及iPhone上的Safari上运行...全部正常...

对我来说看起来很稳定 :)


非常简单,对我来说运行良好。在Android(旧版Galaxy Note)和模拟器(Chrome)上进行了测试,并在iPad上也测试过。 - Ralf
在Chrome上对我来说返回了一个错误的结果。 - James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接