使用 Javascript 检测触摸屏设备

Posted

技术标签:

【中文标题】使用 Javascript 检测触摸屏设备【英文标题】:Detecting touch screen devices with Javascript 【发布时间】:2011-04-27 20:27:06 【问题描述】:

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

我有一个网站,当用户将鼠标悬停在某个项目上时,它会向上滑动一个小信息面板。我正在使用 jQuery.hoverIntent 来检测悬停,但这显然不适用于 iPhone/iPad/android 等触摸屏设备。所以在这些设备上,我想恢复点击以显示信息面板。

【问题讨论】:

为什么不能两者都做?在非触摸屏设备中是否不需要点击功能? 由于一些较新的设备不支持:hover,因此(在为多个设备编写一个样式表时)纯粹出于装饰目的使用:hover 可能会更好。 @empraptor:好点——是的,我能做到。但是...我们也考虑始终在触摸屏设备上显示面板 - 在这种情况下,我需要能够检测到支持。 如果您总是可以在触摸屏设备上显示面板,那么您不能在其他设备上也显示它吗?面板有多大?为什么只在悬停/点击时显示它? What's the best way to detect a 'touch screen' device using JavaScript? 的可能重复项 【参考方案1】:
var isTouchDevice = 'ontouchstart' in document.documentElement;

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

【讨论】:

如 Modernizr 文档中所述,这仅检测 browser 功能,而不是 device 功能...您将在运行支持触摸的浏览器的没有触摸输入的设备。我不知道如何在本地检测 device 触摸功能,而无需等待触摸事件发生。 为了也检测我正在使用的 IE 10 触摸:(window.navigator.msMaxTouchPoints || ('ontouchstart' in document.documentElement)); 'ontouchstart' in document.documentElement 在 BlackBerry 9300 上错误地返回 true @typhon 如果软件(Win 8,现代浏览器)支持触摸,这将永远是正确的——即使您使用的是硬件(台式机、标准显示器、鼠标和键盘)不支持触摸。因此,此解决方案已过时。 funnyItsNotCamelCaseAsJsIsThroughout。我的意思是人们现在需要复制、粘贴和编辑代码...... :)【参考方案2】:

发现对 window.Touch 的测试在 android 上不起作用,但确实如此:

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

见文章:What's the best way to detect a 'touch screen' device using JavaScript?

【讨论】:

这确实会检测到触摸屏,但要小心,因为它也会为带有触摸屏的笔记本电脑返回 TRUE。如果您试图区分用户是来自手机/平板电脑还是计算机/笔记本电脑,这可能会出现问题,因为对于带有触摸屏的笔记本电脑,它会返回 TRUE。【参考方案3】:

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

请看这里:http://www.forabeautifulweb.com/blog/about/hardboiled_css3_media_queries/

【讨论】:

很好的解决方案,您可以使用 one() 绑定执行悬停检查等操作,这样它只会在第一次触发。 问题是,如果您以屏幕宽度为目标,那么当您旋转您的设备(让我们以 iphone 6+ 736x414 为例)时,它将不会具有相同的样式。所以不是最好的解决方案:/【参考方案4】:
if ("ontouchstart" in window || navigator.msMaxTouchPoints) 
    isTouch = true;
 else 
    isTouch = false;

适用于任何地方!

【讨论】:

这和鼠标有什么关系? (实际问题) isTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;会更简单【参考方案5】:
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

【讨论】:

这在谷歌浏览器开发者工具模拟设备中工作和工作谢谢【参考方案6】:

我用:

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

在 jQuery 移动版 1.0.1 中

【讨论】:

jQuery 建议不要使用 jQuery.support 来支持 Modernizr (modernizr.com):参考 - api.jquery.com/jQuery.support -【参考方案7】:

谷歌浏览器似乎在这个上返回误报:

var isTouch = 'ontouchstart' in document.documentElement;

我想它与“模拟触摸事件”的能力有关(F12 -> 右下角的设置 -> “覆盖”选项卡 -> 最后一个复选框)。我知道默认情况下它是关闭的,但这就是我将结果更改与(用于在 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 - 但不再了吗?我没有设置“模拟触摸事件”选项。 呃,总是与新硬件作斗争。浏览器必须与操作系统抽象层一起工作……它并不总是实现所有东西……简而言之,使用 JS 你必须依赖浏览器:) 从来没有通用的方法。 在非触摸笔记本电脑上的 Ubuntu Firefox 上,这两个都返回 true。【参考方案8】:

为我的一个网站写了这篇文章,这可能是最简单的解决方案。尤其是因为即使是 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";

【讨论】:

不过要小心:至少 iPad 也会在鼠标悬停时出现 在 Windows 平板电脑上使用 IE 的人可能希望同时使用触控和鼠标。 这篇文章是在 Windows 平板电脑出现之前发布的。 @s427 - 他妈的 IE... 只需检查 IE8。我认为没有任何带有 【参考方案9】:

对于我的第一篇文章/评论: 我们都知道“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';
);

//

祝你有美好的一天!

【讨论】:

【参考方案10】:

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

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

适用于 android Mozilla、chrome、Opera、android 默认浏览器和 iphone 上的 safari... 都是正面的...

对我来说似乎很可靠:)

【讨论】:

超级简单,对我来说很好用。在 Android(旧版 Galaxy Note)、模拟器 (Chrome) 和 iPad 上进行了测试。 在 Chrome 上为我返回误报。【参考方案11】:

一篇关于该主题的有用博客文章,链接到 Modernizr 源代码以检测触摸事件。结论:无法通过 Javascript 可靠地检测触摸屏设备。

http://www.stucox.com/blog/you-cant-detect-a-touchscreen/

【讨论】:

【参考方案12】:

这对我有用:

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

【讨论】:

您在多少个平台、浏览器、操作系统、设备上进行了测试? FF、Chrome、Safari 在 Android 和 ios (iPad) 上 不错。我刚刚在桌面上进行了测试,得到了很多“未定义”,这使得 IF 结构有点笨拙。如果您稍微调整一下返回值,如下所示: return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);那么你有真假:-) 在 Chrome 中,窗口中的“ontouchstart”在我没有触摸屏的 PC 上是真的,所以这不起作用。如前所述,这会测试浏览器是否具有触控功能。另外,true == 没有任何作用,应该省略。 当我在 Chrome 中使用内置模拟器尝试此操作时,它会在模拟器中打开时检测到触摸,而在关闭时不会检测到触摸。所以对我来说很好。但是:我使用 Prasad 的简短版本(如下),它不使用 ||在 Turtlerail 的代码中。而且:我不在乎它是否适用于 100% 的设备。 99% 会为我做。【参考方案13】:

如果你使用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 将提供比 Windows Phone 更广泛的检测到的 Microsoft 移动设备。

Also see this SO question

【讨论】:

现在对 4 个问题的回答是否相同...这不是他所问问题的解决方案。 我相信它确实回答了这里的问题 这不是答案,但它是我认为谁想要在用户触摸设备之前检测设备是否可触摸的提示【参考方案14】:

在 jQuery Mobile 中你可以简单地做:

$.support.touch

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

【讨论】:

【参考方案15】:

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

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

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

延伸阅读here.

【讨论】:

【参考方案16】:

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

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

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

【讨论】:

这不适用于 Opera Mobile 10 或 Internet Explorer Mobile 6 (Windows Mobile 6.5)。 糟糕的跨浏览器/跨操作系统/跨平台建议。

以上是关于使用 Javascript 检测触摸屏设备的主要内容,如果未能解决你的问题,请参考以下文章

javascript 使用JS检测触摸设备

javascript 用于检测触摸/移动设备的各种JavaScript方法

使用 javascript 检查触摸设备

是否在所有设备中都通过点击事件检测到触摸设备中的触摸?

JavaScript中的Touch事件简介

检测设备是不是有键盘,或者是触摸设备