ChatGPT解决这个技术问题 Extra ChatGPT

使用 Javascript 检测触摸屏设备

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

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

为什么不能两者都做?在非触摸屏设备中是否不需要点击功能?
由于一些较新的设备不支持 :hover,因此(在为多个设备编写一个样式表时)将 :hover 用于纯粹的装饰目的可能会更好。
@empraptor:好点 - 是的,我可以做到。然而......我们也在考虑总是在触摸屏设备上显示面板 - 在这种情况下,我需要能够检测到支持。
如果您始终可以在触摸屏设备上显示面板,那么您不能在其他设备上也显示它吗?面板有多大,为什么只在悬停/点击时显示它?

K
KevBurnsJr
var isTouchDevice = 'ontouchstart' in document.documentElement;

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


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

发现对 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。
A
Ashkan Mobayen Khiabani

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

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


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

无处不在!


这和鼠标有什么关系? (实际问题)
isTouch = "ontouchstart" in window || navigator.msMaxTouchPoints;会更简单
T
Tim Graham
return (('ontouchstart' in window)
      || (navigator.maxTouchPoints > 0)
      || (navigator.msMaxTouchPoints > 0));

使用 maxTouchPoints 和 msMaxTouchPoints 的原因:

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

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


这在谷歌浏览器开发者工具模拟设备中工作和工作谢谢
M
Mark

我用:

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

在 jQuery 移动版 1.0.1 中


jQuery 建议不要使用 jQuery.support 来支持 Modernizr (modernizr.com):参考 - api.jquery.com/jQuery.support -
B
Boyan

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

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。
c
csano

为我的一个网站写了这篇文章,可能是最简单的解决方案。特别是因为即使是 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。我认为没有任何带有 <= IE8 的移动设备。
s
silassare

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

祝你今天过得愉快!


P
Prasad

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

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

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

对我来说似乎很可靠:)


超级简单,对我来说很好用。在 Android(旧 Galaxy Note)和模拟器(Chrome)和 iPad 上测试。
在 Chrome 上为我返回误报。
M
Mike S

一篇关于该主题的有用博客文章,从 Modernizr 源中链接到用于检测触摸事件。结论:不可能从 Javascript 可靠地检测触摸屏设备。

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


T
Turtletrail

这对我有用:

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

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

如果您使用 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 个问题的回答是否相同……这不是他所问问题的解决方案。
我相信它确实回答了这里的问题
这不是答案,但它是我认为谁想要在用户触摸设备之前检测设备是否可触摸的提示
O
OZZIE

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

$.support.touch

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


u
user3792852

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

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

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


H
Halton

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

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

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


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