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

Posted

技术标签:

【中文标题】如何检测浏览器是不是支持鼠标悬停事件?【英文标题】:How do I detect whether a browser supports mouseover events?如何检测浏览器是否支持鼠标悬停事件? 【发布时间】:2011-06-06 07:39:27 【问题描述】:

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

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

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

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

编辑:当我说“支持悬停事件”时,我的真正意思是“浏览器是否具有悬停事件的有意义表示”。如果硬件支持但软件不支持(反之亦然),则没有有意义的表示。除了一些 upcoming tech 之外,我认为没有任何触摸设备能够有意义地表示悬停事件。

【问题讨论】:

我认为您的问题需要重新表述,因为 iPad 在理论上确实支持悬停,但输入使其成为不可能。所以你的问题应该是:我如何检测用户是否有可能将鼠标悬停在一个项目上? 也许这可以给你一个开始:***.com/questions/3974827/… @nightcracker - 从网站(和我)的角度来看,硬件是否能够支持悬停并不重要 - 唯一重要的是是否有有意义的 onmouseover 或onmouseout 钩子。我会在问题中澄清。 @amosriviera - 谢谢你,这个问题中有一些有趣的东西。有一个答案可以让我选择 iPad,但没有跨浏览器。 【参考方案1】:
var supportsTouch = (typeof Touch == "object");

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

更新:考虑到现在一天有多少台设备和Johan 的cmets,我建议直接使用Modernizr。

【讨论】:

这适用于所有/大多数触控设备吗? android 手机和平板电脑、诺基亚触摸屏以及 iWhatevers? Android 和 iThings 99.9%,Symbian?是的,从某些 QtWebKit 版本开始,但不要问我会是哪个版本的 Symbian。 您在寻找替代品吗?考虑 onmousemove 但这将需要超时,并且可能最终会在某些平台上被模拟。 应该注意的是,支持触摸事件的设备不一定是悬停挑战的:它们可能支持不止一种与之交互的方式(例如,笔)。 Surface 平板电脑上的 IE10 和 11 不支持触​​摸事件,即使 Surface 是触摸设备。【参考方案2】:

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

try 
   document.createEvent("TouchEvent");
   alert(true);

catch (e) 
   alert(false);

Read more

【讨论】:

在我一直在测试的机器人中,我根本没有得到公认的答案,但这个很好用。 接受的答案对我也没有任何作用,但这一个成功了!谢谢,约翰。 最新版 Chrome(v. 32,Win7,无触摸屏)的误报。【参考方案3】:

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

"Active pen" digitizer devices 喜欢 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 事件以进行良好的内务管理

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


以混合设备为例:

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

...用鼠标拿一个老式的桌面工作站:

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

【讨论】:

【参考方案4】:

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

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

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

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

【讨论】:

【参考方案5】:

non-legacy browsers 的另一种方法是利用媒体查询 hover 和 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

【讨论】:

很好的答案。我刚刚在三星 Galaxy Note 8 上进行了尝试,链接的“悬停”示例与笔完美配合(悬停时为黄色),但“任意悬停”没有(悬停时没有响应)。很奇怪,因为如果笔是触控后的辅助输入法,我会期望它是相反的吗?

以上是关于如何检测浏览器是不是支持鼠标悬停事件?的主要内容,如果未能解决你的问题,请参考以下文章

在智能手机浏览器上检测悬停或鼠标悬停

C# winfrom程序可以实现按钮的鼠标悬停变色,离开恢复,按下时变成黑色并一直保持吗

在所有浏览器中检测选择选项的鼠标悬停

如何将鼠标悬停在 SVG 矩形上?

JavaScript获取鼠标悬停的文本[重复]

JavaScript获取鼠标悬停的文本[重复]