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

Dam*_*isa 13 javascript html5 browser-detection onmouseover touch

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

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

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

注意:我知道如果我对此感到担心,我应该以不同的方式编写它,但我很好奇是否可以进行检测.

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

Joh*_*han 18

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

try {
   document.createEvent("TouchEvent");
   alert(true);
}
catch (e) {
   alert(false);
}
Run Code Online (Sandbox Code Playgroud)

阅读更多

  • 在我测试过的机器人中,我没有得到完全可以接受的工作答案,但这个很有效. (2认同)
  • 最新版Chrome(第32版,Win7,无触摸屏)出现误报. (2认同)

Tho*_*mas 11

var supportsTouch = (typeof Touch == "object");
Run Code Online (Sandbox Code Playgroud)

只是检测它是否是一个触摸设备,然后做你的特殊事情.这是最简单的方法,因为大多数触摸设备模拟鼠标事件,但没有鼠标驱动设备模拟触摸事件.

更新:考虑到现在有多少设备和Johan的评论,我建议只使用Modernizr.

  • 应当注意,支持触摸事件的设备不一定是悬停挑战的:它们可以支持多种与其交互的方式(例如,笔). (3认同)
  • 这适用于所有/大多数触控设备吗?Android手机和平板电脑,诺基亚触摸屏以及iWhatevers? (2认同)

use*_*ca8 9

这是2016年,现在有很多设备同时具有触摸和鼠标输入."不能触摸" 不是判断"可以鼠标悬停"的好方法.举几个例子:

  • "有源笔"数字化仪设备,如Galaxy Note手机和平板电脑(Android),微软Surface(Windows)和Wacom Cintiq(Mac/Windows/Android),我也相信iPad专业版,它的笔就像鼠标一样可以"空气盘旋"离屏幕约1厘米处
  • 带触摸屏的Windows笔记本电脑/混合动力车和传统的笔记本电脑触控板等
  • 触摸屏显示器,可以连接到任何PC并与鼠标一起使用

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


如果您需要知道您的用户a)是否可以使用和b)当前正在使用的设备能够方便地将其分类,您可以:

  • 绑定mousemove事件到您的文档body激活一个"具有悬停"状态(例如添加一个类user-can-mouseoverbody)如果鼠标移动触发光标移动,然后立即解除绑定本身,因此只会发生一次.
  • 还绑定touchstart暂时停用该事件mousemovetouchend重新激活它的事件,以便在触发触发鼠标事件的浏览器上(在Android和Windows上很常见),正常的触摸滚动不会触发mousemove.
  • mousemove活动解开这些touchstarttouchend活动以获得良好的内务管理

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


例如,采用混合设备:

  1. 最初,用户使用触摸和滑动浏览网页.
  2. 它们到达您的应用程序,使用触摸向上和向下滑动,同时了解它是什么.到目前为止,"可以悬停"的情况并不活跃.
  3. 他们认为这是他们想要比他们的胖手指允许更准确的情况之一,因此他们拉出数字化笔或伸手去拿鼠标.
  4. 这会导致光标在页面上移动而没有发生未触发的触摸事件,因此触发了"可悬停"状态

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

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


Tay*_*lan 5

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

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
Run Code Online (Sandbox Code Playgroud)