禁用移动浏览器上的悬停效果背景解决方案说明替代解决方案延伸阅读

2022-08-30 05:04:38

我正在编写一个网站,旨在从台式机和平板电脑上使用。当从桌面访问它时,我希望屏幕的可点击区域以效果(不同的背景颜色等)亮起。使用平板电脑,没有鼠标,所以我不想要任何悬停效果。:hover

问题是,当我在平板电脑上点击某些东西时,浏览器显然有某种“看不见的鼠标光标”,它会移动到我点击的位置,然后把它留在那里 - 所以我刚刚点击的东西会以悬停效果亮起,直到我点击其他东西。

如何在使用鼠标时获得悬停效果,但在使用触摸屏时禁止显示它们?

如果有人想建议它,我不想使用用户代理嗅探。同一设备可以同时具有触摸屏和鼠标(今天可能不那么常见,但将来会更常见)。我对设备不感兴趣,我对它目前的使用方式感兴趣:鼠标或触摸屏。

我已经尝试过挂接 ,和 事件并调用所有事件,这确实在某些时候会抑制“不可见的鼠标光标”;但是,如果我在两个不同的元素之间快速来回点击,在点击几下后,它将开始移动“鼠标光标”并照亮悬停效果 - 就像我并不总是受到尊重一样。除非有必要,否则我不会让你厌倦细节 - 我甚至不确定这是正确的方法;如果有人有更简单的解决方法,我全都洗耳恭听。touchstarttouchmovetouchendpreventDefault()preventDefault


编辑:这可以用沼泽标准的CSS复制,但这里有一个快速的重现供参考。:hover

<style>
  .box { border: 1px solid black; width: 150px; height: 150px; }
  .box:hover { background: blue; }
</style>
<div class="box"></div>
<div class="box"></div>

如果您将鼠标悬停在其中一个框上,它将获得我想要的蓝色背景。但是,如果您点击其中任何一个框,它也将获得蓝色背景,这是我试图阻止的事情。

我还在这里发布了一个示例,可以执行上述操作,还可以挂钩jQuery的鼠标事件。您可以使用它来查看 tap 事件也会触发 ,和 。mouseentermousemovemouseleave


答案 1

我从您的问题中得出您的悬停效果会更改页面内容。在这种情况下,我的建议是:

  • 触摸启动鼠标进入器上添加悬停效果。
  • 删除鼠标悬停效果,触摸移动单击

或者,您可以编辑没有内容更改的页面。

背景

为了模拟鼠标,如果用户在触摸屏(如 iPad)上触摸并释放手指,则 Webkit 移动等浏览器会触发以下事件(来源:html5rocks.com 上的触摸和鼠标):

  1. touchstart
  2. touchmove
  3. touchend
  4. 300ms延迟,浏览器确保这是一次点击,而不是双击
  5. mouseover
  6. mouseenter
    • 注意:如果 或 事件更改了页面内容,则永远不会触发以下事件。mouseovermouseentermousemove
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

似乎不可能简单地告诉Web浏览器跳过鼠标事件。

更糟糕的是,如果鼠标悬停事件更改了页面内容,则永远不会触发单击事件,如 Safari Web 内容指南 - 处理事件中所述,尤其是单指事件中的图 6.4。究竟什么是“内容更改”,将取决于浏览器和版本。我发现对于iOS 7.0,背景颜色的变化不是(或不再是?)内容变化。

解决方案说明

回顾一下:

  • 在 和 上添加悬停效果。touchstartmouseenter
  • 删除 对 和 的悬停效果。mouseleavetouchmoveclick

请注意,没有对 !touchend

这显然适用于鼠标事件:并且(和)的略微改进版本被触发,并添加和删除悬停。mouseentermouseleavemouseovermouseout

如果用户实际上是一个链接,则悬停效果也会被删除。这可确保在用户按下 Web 浏览器中的后退按钮时将其删除。click

这也适用于触摸事件:在触摸启动时,将添加悬停效果。它是“不”在触摸端删除的。它在 上再次添加,并且由于这会导致任何内容更改(已添加),因此也会触发该事件,并且无需用户再次单击即可跟踪链接!mouseenterclick

浏览器在事件之间具有的300ms延迟实际上得到了很好的利用,因为悬停效果将在这短时间内显示。touchstartclick

如果用户决定取消单击,手指的移动将像往常一样执行此操作。通常,这是一个问题,因为不会触发任何事件,并且悬停效果仍然存在。值得庆幸的是,可以通过删除 上的悬停效果来轻松解决此问题。mouseleavetouchmove

就是这样!

请注意,可以删除300ms延迟,例如使用FastClick库,但这超出了此问题的范围。

替代解决方案

我发现以下替代方案存在以下问题:

  • 浏览器检测:非常容易出错。假设设备具有鼠标或触摸功能,而当触摸显示器出现时,两者的组合将变得越来越普遍。
  • CSS 媒体检测:我所知道的唯一一个仅CSS解决方案。仍然容易出错,并且仍然假设设备具有鼠标或触摸,而两者都是可能的。
  • 触屏中模拟点击事件:这将错误地跟踪链接,即使用户只想滚动或缩放,而无意实际单击链接。
  • 使用变量禁止显示鼠标事件:这将设置一个变量,该变量在后续鼠标事件中用作 if 条件,以防止在该时间点的状态更改。变量在单击事件中重置。请参阅此页面上沃尔特·罗曼的答案。如果您真的不希望在触摸界面上出现悬停效果,这是一个不错的解决方案。不幸的是,如果由于其他原因触发了 a 并且没有触发任何单击事件(例如,用户滚动或缩放),并且随后尝试使用鼠标跟踪链接(即在同时具有鼠标和触摸界面的设备上),则此操作不起作用。touchendtouchend

延伸阅读


答案 2

如何在使用鼠标时获得悬停效果,但在使用触摸屏时禁止显示它们?

也许不要把它想象成抑制触摸屏的悬停效果,而是为鼠标事件添加悬停效果?

如果你想在CSS中保留效果,你可以为不同的媒体指定不同的样式::hover

@media screen { /* hover styles here */ } 

@media handheld { /* non-hover styles here */ }

除了不幸的是,有很多移动设备忽略了这一点,只使用屏幕规则。幸运的是,许多较新的移动/平板电脑浏览器确实支持一些更花哨的媒体查询:

@media screen and (max-width:800px) { /* non-hover styles here */ }

因此,即使忽略“屏幕”或“手持”部分,“最大宽度”也会为您解决问题。您可以假设屏幕小于800像素的任何内容都必须是平板电脑或手机,并且不使用悬停效果。对于在低分辨率设备上使用鼠标的罕见用户,他们不会看到悬停效果,但您的网站会很好。

进一步阅读媒体查询?网上有很多关于此的文章 - 这里有一个:http://www.alistapart.com/articles/return-of-the-mobile-stylesheet

如果您将悬停效果移出CSS并使用JavaScript应用它们,那么您可以专门绑定到鼠标事件,并且/或者您可以再次仅根据屏幕大小做出一些假设,最坏情况下的“问题”是某些使用鼠标的用户错过了悬停效果。