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

发布于 2024-10-11 01:26:17 字数 495 浏览 6 评论 0原文

假设我有一个网页,其中有一些 onmouseover javascript 行为来下拉菜单(或类似的东西)。

显然,这不适用于 iPad 或智能手机等触摸设备。

如何检测浏览器是否支持 onmouseover 或 onmouseout 等悬停事件以及 CSS 中的 :hover 伪标记?

注意:我知道如果我担心这一点,我应该以不同的方式编写它,但是我很好奇是否可以进行检测。

编辑:当我说“支持悬停事件”时,我的真正意思是“浏览器是否对悬停事件有有意义的表示”。如果硬件支持但软件不支持(反之亦然),则没有有意义的表示。除了一些即将推出的技术,我认为任何触摸设备都没有悬停事件的有意义的表示

Let's assume I have a web page which has some onmouseover javascript behaviour to drop down a menu (or something similar)

Obviously, this isn't going to work on a touch device like the iPad or smartphones.

How can I detect whether the browser supports hover events like onmouseover or onmouseout and the :hover pseudotag in CSS?

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

坐在坟头思考人生 2024-10-18 01:26:17

此方法可捕获更多设备/浏览器

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

了解更多

This method catches more devices/browsers

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

Read more

隔纱相望 2024-10-18 01:26:17
var supportsTouch = (typeof Touch == "object");

只需检测它是否是触摸设备,然后执行您的特殊操作即可。
这是最简单的方法,因为大多数触摸设备模拟鼠标事件,但没有鼠标驱动设备模拟触摸事件。

更新:考虑到现在每天有多少设备以及 Johan 的评论,我会建议仅使用 Modernizr

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.

可爱暴击 2024-10-18 01:26:17

现在是 2016 年,很多设备都同时具备触摸和类似鼠标的输入功能,这已经好几年了。 “无法触摸”不是判断“可以鼠标悬停”的好方法。仅举几个示例:

  • “有源笔”数字化仪设备,例如 Galaxy Note 手机和平板电脑 (Android )、Microsoft Surface (Windows) 和 Wacom Cintiq (Mac/Windows/Android),我相信 iPad Pro 也是如此,其中笔的工作方式类似于鼠标,在距离屏幕约 1 厘米时可以“悬停”
  • Windows 笔记本电脑/混合笔记本电脑触摸屏以及传统的笔记本电脑触控板等
  • 可以连接到任何 PC 并与鼠标一起使用的触摸屏显示器

因此,用户可能无法悬停一分钟,然后,在同一设备上,无需刷新页面,他们就会将笔从他们的 Galaxy Note(假设它没有着火)突然在交互中使用悬停,并且他们希望它能正常工作。


如果您需要了解您的用户是否 a) 可以 使用并且 b) 目前正在使用能够方便地移动鼠标的设备,您可以:

  • 将一个 mousemove 事件绑定到您的文档 body 来激活“有悬停”状态(例如添加一个类 user-can-mouseover body) 如果鼠标移动触发的光标正在移动,然后立即解除自身绑定,因此它只发生一次。
  • 还绑定一个 touchstart 事件来暂时停用 mousemove 和一个 touchend 来重新激活它,这样,在触摸时触发鼠标事件的浏览器上(在 Android 和 Windows 上很常见),正常的触摸滚动不会触发 mousemove
  • mousemove 事件取消绑定这些 touchstarttouchend 事件,以便进行良好的内务管理。

这将导致“可以悬停”状态在任何时候被触发。用户开始使用行为类似于鼠标的输入设备。


例如,以混合设备为例:

  1. 最初,用户使用触摸和滑动来浏览网页。
  2. 他们到达您的应用程序,使用触摸上下滑动,同时了解它是什么。到目前为止,“可以悬停”条件尚未激活。
  3. 他们认为这是他们想要比胖手指允许的更高精确度的情况之一,因此他们拿出数字笔或伸手去拿鼠标。
  4. 这会导致光标在页面上移动,而不会发生未结束的触摸事件,因此您的“可以悬停”条件被触发

......并使用鼠标使用老式桌面工作站:

  1. 页面加载。
  2. 用户在做任何事情的同时移动鼠标,立即触发鼠标移动事件
  3. “可以悬停”状态立即触发

It's 2016 and plenty of devices have both touch and mouse-like inputs for several years now. "Can't touch" is not a good way to judge "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
  • Windows laptops / hybrids with touchscreens plus and convential laptop trackpads etc
  • Touchscreen monitors that can be attached to any PC and used with a mouse

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.


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:

  • Bind a mousemove event to your document body that activates a "has hover" state (e.g. 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.
  • 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.
  • Have the mousemove event unbind these touchstart and touchend events for good housekeeping

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
玉环 2024-10-18 01:26:17

非旧版浏览器的另一种方法是利用媒体查询悬停任意悬停

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

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
原野 2024-10-18 01:26:17

基于 user568458 的响应的一组功能,允许您打开/关闭触摸设备的 :hover 样式(我没有在所有设备上尝试过):

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

然后您可以在样式表中的任何 :hover 选择器之前使用 .hoverActive 来防止移动浏览器尝试显示悬停状态。

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):

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文