如何检测浏览器是不是支持鼠标悬停事件?
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
事件取消绑定这些 touchstart
和 touchend
事件以进行良好的内务管理
这将导致在用户开始使用行为类似于鼠标的输入设备时触发“可以悬停”状态。
以混合设备为例:
-
最初,用户使用触摸和滑动浏览网页。
他们到达您的应用程序,使用触摸上下滑动,同时了解它是什么。到目前为止,“可以悬停”条件尚未激活。
他们认为这是他们想要比他们的胖手指更精确的情况之一,因此他们拔出数字化笔或伸手去拿鼠标。
这会导致光标在页面上移动而不会发生未结束的触摸事件,因此会触发“可以悬停”条件
...用鼠标拿一个老式的桌面工作站:
-
页面加载。
用户在做任何事情时移动鼠标,立即触发鼠标移动事件
立即触发“可以悬停”状态
【讨论】:
【参考方案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 上进行了尝试,链接的“悬停”示例与笔完美配合(悬停时为黄色),但“任意悬停”没有(悬停时没有响应)。很奇怪,因为如果笔是触控后的辅助输入法,我会期望它是相反的吗?以上是关于如何检测浏览器是不是支持鼠标悬停事件?的主要内容,如果未能解决你的问题,请参考以下文章