使用Javascript检测触摸屏设备


129

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

我有一个网站,当用户将鼠标悬停在某个项目上时,该网站会在信息面板上滑动。我正在使用jQuery.hoverIntent来检测悬停,但这显然不适用于iPhone / iPad / Android等触摸屏设备。因此,在这些设备上,我想还原为点按以显示信息面板。


6
你们为什么不能两者都做?在非触摸屏设备中,点击功能是否不可取?
EMPraptor

1
由于某些较新的设备不支持:hover,因此(:hover纯粹为多个设备编码一个样式表时)最好用于纯粹的装饰目的。
德拉吉

@empraptor:好点-是的,我可以做到。但是...我们还考虑始终在触摸屏设备上显示面板-在这种情况下,我需要能够检测到支持。
布拉德·罗宾逊

如果您始终可以在触摸屏设备上显示该面板,那么是否也不能在其他设备上显示它呢?面板有多大?为什么希望仅在悬停/轻击时显示它?
EMPraptor

Answers:


12

+1做hoverclick两者。另一种方法是使用CSS媒体查询,并且仅对较小的屏幕/移动设备使用某些样式,而较小的屏幕/移动设备最可能具有触摸/点击功能。因此,如果您通过CSS有一些特定的样式,并且从jQuery中检查了移动设备样式属性中的那些元素,则可以将它们挂钩以编写您的移动特定代码。

参见此处:http : //www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/


1
好的解决方案,您可能会执行一个带有one()绑定的悬停检查,因此它只会在第一次触发时执行。
蒂莫西·佩雷斯

问题是,如果您按屏幕宽度作为目标,那么在旋转设备时(以iphone 6+ 736x414为例),它将不会具有相同的样式。所以不是最好的解决方案:/
antoni

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

注意:仅仅因为设备支持触摸事件,并不一定意味着它仅是触摸屏设备。许多设备(例如华硕Zenbook)都支持单击和触摸事件,即使它们没有任何实际的触摸输入机制也是如此。在设计触摸支持时,请始终包括单击事件支持,并且永远不要假设任何设备都是彼此独占的。


33
如Modernizr文档中所述,这仅检测浏览器功能,而不检测设备功能...如果在没有触摸输入的设备上运行触摸功能的浏览器,您将得到假阳性结果。我不知道一种方法来本地检测设备的触摸功能,而不仅仅是等待触摸事件发生。
Stu Cox

12
为了还检测IE 10触摸,我正在使用:(window.navigator.msMaxTouchPoints ||(document.documentElement中的“ ontouchstart”));
亚历山大·凯利特

2
'ontouchstart' in document.documentElement 黑莓9300不正确地返回true
简单的

10
@typhon(如果软件(Win 8,现代浏览器)支持触摸),即使您使用的是不支持触摸的硬件(台式机,标准显示器,鼠标和键盘),也总是如此。因此,此解决方案已过时。
巴尼2014年

1
funnyItsNotCamelCaseAsJsIsThroughout。我的意思是,人们现在需要复制,粘贴和编辑代码。:)
罗斯

20

找到了针对window.Touch的测试,但在android上不起作用,但这可以做到:

function is_touch_device() {
  return !!('ontouchstart' in window);
}

请参阅文章:使用JavaScript检测“触摸屏”设备的最佳方法是什么?


这确实可以检测到触摸屏,但是要小心,因为它对于带有触摸屏的笔记本电脑也返回TRUE。如果您试图区分用户是来自电话/平板电脑还是计算机/笔记本电脑,这可能是个问题,因为对于带触摸屏的笔记本电脑,它返回TRUE。
合并

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

将maxTouchPoints与msMaxTouchPoints一起使用的原因:

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

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


这在谷歌浏览器的chrome开发人员工具中起作用并工作过,模拟设备谢谢您
Behnam Mohammadi

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

在任何地方都可以使用!


那和鼠标有什么关系?(实际问题)
hexalys 2014年

这样会更简单isTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;
安德鲁(Andrew)


4

谷歌浏览器似乎对此返回了误报:

var isTouch = 'ontouchstart' in document.documentElement;

我想它与“模拟触摸事件”的功能有关(F12->右下角的设置->“ Overrides”选项卡->最后一个复选框)。我知道默认情况下它是关闭的,这就是我将结果更改与之关联的原因(用于Chrome的“ in”方法)。但是,据我测试,这似乎可行:

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

我在所有浏览器上都以typeof状态运行该代码都是“对象”,但是我更确定地知道它除了未定义之外是什么:-)

在IE7,IE8,IE9,IE10,Chrome 23.0.1271.64,Chrome for iPad 21.0.1180.80和iPad Safari上进行了测试。如果有人再做一些测试并共享结果,那将很酷。


两种方法都在带有FF 23和Chrome 28的Win 8 PC上返回误报。是否总是这样?或者是因为我曾经在这台计算机上安装了触摸屏(可能是在安装FF和Chrome之前),但现在不再了吗?我没有设置“模拟触摸事件”选项。
Typhon

嗯,新硬件总是很挣扎。浏览器必须与OS抽象层配合使用……它们并不总是实现所有功能……简而言之,使用JS时,您必须依靠浏览器:)从来没有一种通用的方法。
2013年

两者在非触摸式笔记本电脑上的Ubuntu Firefox上都返回true。
NoBugs 2015年

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也会引发
鼠标悬停

14
该死的苹果!
蒂莫西·佩雷斯

在Windows平板电脑上使用IE的人们可能希望同时使用触摸和鼠标。
塞巴兹(Sebazzz)2013年

这篇文章是在Windows Tablet出现之前发布的。
蒂莫西·佩雷斯

@ s427-Fecking IE ...只需检查IE8。我认为没有<= IE8的移动设备。
蒂莫西·佩雷斯

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

祝你今天愉快!


3

我已经测试了上面讨论中提到的以下代码

 function is_touch_device() {
    return !!('ontouchstart' in window);
 }

适用于Android Mozilla,Chrome,Opera,Android默认浏览器和iPhone上的Safari。

对我来说似乎很可靠:)


超级简单,适合我。已在Android(旧版Galaxy Note),模拟器(Chrome)和iPad上进行了测试。
2015年

在Chrome上为我返回误报。
詹姆斯


2

这对我有用:

function isTouchDevice(){
    return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}

1
您测试了多少平台,浏览器,OS'设备?
BerggreenDK 2013年

1
FF,Chrome,Android和iOS(iPad)上的Safari
Turtletrail

1
很好 我刚刚在台式机上进行了测试,并得到了很多“未定义”的信息,这使得IF结构有些古怪。如果您只是稍微调整一下返回值,就像这样:return true ==(“ || window.DocumentTouch && DocumentTouch的documentTouch”窗口中的“ ontouchstart”);那么您是对还是错:-)
BerggreenDK 2013年

2
在Chrome中,在没有触摸屏的PC上,窗口中的“ ontouchstart”是正确的,因此不起作用。如前所述,这将测试浏览器是否支持触摸功能。另外,true ==不执行任何操作,应省略。
rakensi 2014年

1
当我在Chrome中使用内置的模拟器尝试此操作时,在模拟器中打开电源时它将检测到触摸,而在关闭电源时则不会检测到触摸。所以对我来说很好。但是:我使用的是Prasad的简短版本(下),该版本不使用||。在Turtletrail的代码中。并且:我不在乎它是否适用于100%的设备。99%会为我做。
2015年

1

如果您使用Modernizr,则非常容易使用Modernizr.touch如前所述。

但是,Modernizr.touch为了安全起见,我更喜欢结合使用和用户代理测试。

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

if (isTouchDevice) {
        //Do something touchy
    } else {
        //Can't touch this
    }

如果您不使用Modernizr,则只需替换 Modernizr.touch上面函数('ontouchstart' in document.documentElement)

另请注意,与相比,测试用户代理iemobile将为您提供更广泛的检测到的Microsoft移动设备Windows Phone

另请参阅此问题


2
现在对4个问题的回答都是一样的...这不是他所问问题的解决方案。
jycr753

1
我相信它在这里回答这个问题
彼得·潘

这不是答案,而是一个提示,我认为对于谁想在用户触摸设备之前检测设备是否可触摸的人
Shahadat Hossain Khan

1

在jQuery Mobile中,您可以简单地执行以下操作:

$.support.touch

不知道为什么这么没记载。.但是它是跨浏览器安全的(当前浏览器的最新2个版本)。


0

如前所述,设备可以同时支持鼠标和触摸输入。通常,问题不是“支持什么”,而是“当前使用的是什么”。

对于这种情况,您可以简单地注册鼠标事件(包括悬停侦听器)和触摸事件。

element.addEventListener('touchstart',onTouchStartCallback,false);

element.addEventListener('onmousedown',onMouseDownCallback,false);

...

JavaScript应根据用户输入自动调用正确的侦听器。因此,如果发生触摸事件,onTouchStartCallback将触发它,模拟您的悬停代码。

请注意,触摸可能会触发两种听众,即触摸和鼠标。但是,触摸侦听器排在最前面,可以通过调用阻止后续的鼠标侦听器触发event.preventDefault()

function onTouchStartCallback(ev) {
    // Call preventDefault() to prevent any further handling
    ev.preventDefault();
    your code...
}

在这里进一步阅读。


-3

对于iPad开发,我正在使用:

  if (window.Touch)
  {
    alert("touchy touchy");
  }
  else
  {
    alert("no touchy touchy");
  }

然后,我可以选择性地绑定到基于触摸的事件(例如ontouchstart)或基于鼠标的事件(例如onmousedown)。我尚未在android上进行过测试。


1
这不适用于Opera Mobile 10或Internet Explorer Mobile 6(Windows Mobile 6.5)。
doubleJ 2012年

4
跨浏览器/跨OS /跨平台建议不正确。
BerggreenDK
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.