简体   繁体   English

如何检测浏览器是否支持鼠标悬停事件?

[英]How do I detect whether a browser supports mouseover events?

Let's assume I have a web page which has some onmouseover javascript behaviour to drop down a menu (or something similar)假设我有一个网页,它有一些 onmouseover javascript 行为来下拉菜单(或类似的东西)

Obviously, this isn't going to work on a touch device like the iPad or smartphones.显然,这不适用于 iPad 或智能手机等触控设备。

How can I detect whether the browser supports hover events like onmouseover or onmouseout and the :hover pseudotag in CSS?如何检测浏览器是否支持悬停事件,如 onmouseover 或 onmouseout 以及 CSS 中的 :hover 伪标签?

Note: I know that if I'm concerned about this I should write it a different way, but I'm curious as to whether detection can be done.注意:我知道如果我对此感到担心,我应该以不同的方式编写它,但我很好奇是否可以进行检测。

Edit: When I say, "supports hover events", I really mean, "does the browser have a meaningful representation of hover events".编辑:当我说“支持悬停事件”时,我的意思是“浏览器是否对悬停事件具有有意义的表示”。 If the hardware supports it but the software doesn't (or vice versa), there's no meaningful representation.如果硬件支持而软件不支持(反之亦然),则没有有意义的表示。 With the exception of some upcoming tech , I don't think any touch devices have a meaningful representation of a hover event.除了一些即将到来的技术,我认为任何触摸设备都没有有意义的悬停事件表示

This method catches more devices/browsers此方法捕获更多设备/浏览器

try {
   document.createEvent("TouchEvent");
   alert(true);
}
catch (e) {
   alert(false);
}

Read more阅读更多

var supportsTouch = (typeof Touch == "object");

Just detect if it's a touch device and then do your special stuff.只需检测它是否是触摸设备,然后执行您的特殊操作即可。 This is the simplest approach since most touch devices emulate mouse events but no mouse driven device emulates touch events.这是最简单的方法,因为大多数触摸设备模拟鼠标事件,但没有鼠标驱动设备模拟触摸事件。

Update: Considering how many devices there are now a days and Johan 's comments I'd recommend simply using Modernizr .更新:考虑到现在有多少设备以及Johan的评论,我建议只使用Modernizr

It's 2016 and plenty of devices have both touch and mouse-like inputs for several years now.现在是 2016 年,许多设备都具有触摸和类似鼠标的输入已有好几年了。 "Can't touch" is not a good way to judge "Can mouseover" . “Can't touch”不是判断“Can mouseover”的好方法 To give just a few examples:举几个例子:

  • "Active pen" digitizer devices like Galaxy Note phones and tablets (Android), Microsoft Surface (Windows) and Wacom Cintiq (Mac/Windows/Android), and I believe the iPad Pro too, where the pen works like a mouse and can "air hover" when around 1cm from the screen “有源笔”数字化设备,如 Galaxy Note 手机和平板电脑 (Android)、Microsoft Surface (Windows) 和 Wacom Cintiq (Mac/Windows/Android),我相信 iPad Pro 也是如此,它的笔像鼠标一样工作并且可以“空中悬停”距离屏幕约 1 厘米时
  • Windows laptops / hybrids with touchscreens plus and convential laptop trackpads etc Windows 笔记本电脑/带触摸屏的混合动力车和普通笔记本电脑触控板等
  • Touchscreen monitors that can be attached to any PC and used with a mouse可以连接到任何 PC 并与鼠标一起使用的触摸屏显示器

So a user could be unable to hover one minute, then, on the same device, without refreshing the page, they pull the pen out of their Galaxy Note and (assuming it doesn't catch fire) they suddenly are using hover in their interaction, and they expect it to Just Work.因此,用户可能无法悬停一分钟,然后,在同一设备上,不刷新页面,他们将笔从 Galaxy Note 中拔出,并且(假设它没有着火)他们突然在交互使用悬停,他们希望它能够正常工作。


If you need to know if your user a) can use and b) currently is using a device that enables them to conveniently mousover things, you could:如果您需要知道您的用户 a) 是否可以使用并且 b) 当前正在使用使他们能够方便地移动鼠标的设备,您可以:

  • Bind a mousemove event to your document body that activates a "has hover" state (eg adding a class user-can-mouseover to body ) if a mousemove-triggering cursor is moving, and then immediately unbinds itself so it only happens once.如果触发鼠标移动的光标正在移动,则将mousemove事件绑定到您的文档body ,该事件激活“已悬停”状态(例如,将类user-can-mouseoverbody ),然后立即解除绑定,使其只发生一次。
  • Also bind a touchstart event that temporarily deactivates that mousemove and a touchend that reactivates it, so that, on browsers that trigger mouse events on touch (quite common on Android and Windows), normal touch scrolling doesn't trigger the mousemove .同时绑定一个touchstart暂时停用该事件mousemovetouchend是重新激活它,这样,在浏览器上触发式鼠标事件(在Android和Windows很常见),正常触摸滚动不会触发mousemove
  • Have the mousemove event unbind these touchstart and touchend events for good housekeepingmousemove事件解除这些touchstarttouchend事件的绑定, touchend进行良好的管理

This would then cause the "can hover" state to be triggered any time a user starts using an input device that behaves like a mouse.这将导致在用户开始使用行为类似于鼠标的输入设备时触发“可以悬停”状态。


For example, taking a hybrid device:以混合设备为例:

  1. Initially, the user is browsing the web using touch and swipe.最初,用户正在使用触摸和滑动来浏览网页。
  2. They reach your application, swipe up and down using touch while understanding what it is.他们到达您的应用程序,使用触摸上下滑动,同时了解它是什么。 So far, the "can hover" condition isn't active.到目前为止,“可以悬停”条件尚未激活。
  3. They decide this is one of those cases where they want more accuracy than their fat fingers allow, so they pull out the digitizer pen or reach for their mouse.他们认为这是他们想要比他们的胖手指所允许的精度更高的情况之一,因此他们拔出数字化笔或伸手去拿鼠标。
  4. This causes the cursor to move across the page without an unended touch event having happened, so your "can hover" condition is triggered这会导致光标在页面上移动而没有发生无休止的触摸事件,因此您的“可以悬停”条件被触发

...and taking an old-school desktop workstation with a mouse: ...并使用鼠标获取老式桌面工作站:

  1. The page loads.页面加载。
  2. The user moves the mouse while doing anything, immediately triggering the mouse move event用户在做任何事情时移动鼠标,立即触发鼠标移动事件
  3. The "can hover" state is triggered immediately立即触发“可以悬停”状态

Set of functions based on user568458's response that allows you to turn on/off :hover styles for touch devices (I haven't tried it on all devices):基于 user568458 的响应的一组功能,允许您打开/关闭触摸设备的 :hover 样式(我还没有在所有设备上尝试过):

function detectMouseMove() {
    $(document).one('mousemove', function() { 
        $('body').addClass('hoverActive');
        detectTouchEvent();
    });
}
function detectTouchEvent() {
    $(document).one('touchstart', function() { 
        $('body').removeClass('hoverActive');
        detectMouseMove();
    });
}

Then you can just use .hoverActive in your stylesheet before any :hover selectors to prevent mobile browsers from trying to display the hover state.然后,您可以在任何 :hover 选择器之前在样式表中使用 .hoverActive 以防止移动浏览器尝试显示悬停状态。

Another approach for non-legacy browsers is taking advantage of media queries hover and any-hover非传统浏览器的另一种方法是利用媒体查询悬停任意悬停

matchMedia('(hover: hover)').matches; // Primary device can hover

matchMedia('(hover: none)').matches; // Primary device cannot hover

matchMedia('(any-hover: hover)').matches; // At least one of the connected devices can hover

matchMedia('(any-hover: none)').matches; // None of the connected devices can hover

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM