我正在编写一个可以在台式机和平板电脑上使用的网站.当从桌面访问它时,我希望屏幕的可点击区域以 :hover
效果(不同的背景颜色等)点亮.使用平板电脑,没有鼠标,所以我没有不想要任何悬停效果.
I'm writing a Web site that's meant to be used from both desktops and tablets. When it's being visited from a desktop, I want the clickable areas of the screen to light up with :hover
effects (different background color, etc.) With a tablet, there's no mouse, so I don't want any hover effects.
问题是,当我在平板电脑上点击某些东西时,浏览器显然有某种隐形鼠标光标",它会移动到我点击的位置,然后将其留在那里——所以我刚刚点击的东西会亮起在我点击其他东西之前,会出现悬停效果.
The problem is, when I tap something on the tablet, the browser evidently has some kind of "invisible mouse cursor" that it moves to the location I tapped, and then leaves it there -- so the thing I just tapped lights up with a hover effect until I tap something else.
如何在使用鼠标时获得悬停效果,但在使用触摸屏时抑制它们?
如果有人想建议它,我不想使用用户代理嗅探.同一个设备可以同时具有触摸屏和鼠标(今天可能不那么普遍,但将来会更普遍).我对设备不感兴趣,我对它当前的使用方式感兴趣:鼠标或触摸屏.
In case someone was thinking of suggesting it, I don't want to use user-agent sniffing. The same device could have both a touchscreen and a mouse (maybe not so common today, but much more so in the future). I'm not interested in the device, I'm interested in how it's currently being used: mouse or touchscreen.
我已经尝试挂钩 touchstart
、touchmove
和 touchend
事件并在所有事件上调用 preventDefault()
其中,有时确实会抑制隐形鼠标光标";但是如果我在两个不同的元素之间来回快速点击,点击几下后它会开始移动鼠标光标"并点亮悬停效果——就像我的 preventDefault
并不总是荣幸.除非必要,否则我不会让你厌烦细节——我什至不确定这是正确的方法;如果有人有更简单的解决方法,我会全力以赴.
I already tried hooking the touchstart
, touchmove
, and touchend
events and calling preventDefault()
on all of them, which does suppress the "invisible mouse cursor" some of the time; but if I tap rapidly back and forth between two different elements, after a few taps it will start moving the "mouse cursor" and lighting up the hover effects anyway -- it's like my preventDefault
isn't always honored. I won't bore you with the details unless necessary -- I'm not even sure that's the right approach to take; if anyone has a simpler fix, I'm all ears.
这可以用沼泽标准 CSS :hover
重现,但这里有一个快速复制供参考.
This can be reproduced with bog-standard CSS :hover
, but here's a quick repro for reference.
<style>
.box { border: 1px solid black; width: 150px; height: 150px; }
.box:hover { background: blue; }
</style>
<div class="box"></div>
<div class="box"></div>
如果您将鼠标悬停在任何一个框上,它将获得我想要的蓝色背景.但是,如果您点击其中任何一个框,它也会得到蓝色背景,这是我试图阻止的事情.
If you mouse over either of the boxes, it will get a blue background, which I want. But if you tap on either of the boxes, it will also get a blue background, which is the thing I'm trying to prevent.
我还发布了一个示例 here,它执行上述操作并与 jQuery 挂钩鼠标事件.您可以使用它来查看点击事件也会触发 mouseenter
、mousemove
和 mouseleave
.
I've also posted a sample here that does the above and also hooks jQuery's mouse events. You can use it to see that tap events will also fire mouseenter
, mousemove
and mouseleave
.
我从您的问题中得知,您的悬停效果会改变您页面的内容.在这种情况下,我的建议是:
I take it from your question that your hover effect changes the content of your page. In that case, my advice is to:
touchstart
和 mouseenter
上添加悬停效果.mouseleave
、touchmove
和 click
上的悬停效果.touchstart
and mouseenter
.mouseleave
, touchmove
and click
.或者,您可以编辑没有内容更改的页面.
Alternatively, you can edit your page that there is no content change.
为了模拟鼠标,如果用户在触摸屏(如 iPad)上触摸并释放手指,Webkit mobile 等浏览器会触发以下事件(来源:触摸和鼠标 on html5rocks.com):
In order to simulate a mouse, browsers such as Webkit mobile fire the following events if a user touches and releases a finger on touch screen (like iPad) (source: Touch And Mouse on html5rocks.com):
touchstart
touchmove
touchend
鼠标悬停
鼠标输入
mouseover
、mouseenter
或 mousemove
事件改变了页面内容,则以下事件为从未被解雇.touchstart
touchmove
touchend
mouseover
mouseenter
mouseover
, mouseenter
or mousemove
event changes the page content, the following events are never fired.似乎不可能简单地告诉网络浏览器跳过鼠标事件.
更糟糕的是,如果鼠标悬停事件更改了页面内容,则永远不会触发 click 事件,如 Safari Web 内容指南 - 处理事件,尤其是单指事件中的图 6.4.内容更改"究竟是什么,将取决于浏览器和版本.我发现对于 iOS 7.0,背景颜色的更改不是(或不再是?)内容更改.
What's worse, if a mouseover event changes the page content, the click event is never fired, as explained on Safari Web Content Guide - Handling Events, in particular figure 6.4 in One-Finger Events. What exactly a "content change" is, will depend on browser and version. I've found that for iOS 7.0, a change in background color is not (or no longer?) a content change.
回顾一下:
touchstart
和 mouseenter
上添加悬停效果.mouseleave
、touchmove
和 click
上的悬停效果.touchstart
and mouseenter
.mouseleave
, touchmove
and click
.注意 touchend
上没有任何动作!
Note that there is no action on touchend
!
这显然适用于鼠标事件:mouseenter
和 mouseleave
(mouseover
和 mouseout
的略微改进版本)被触发,然后添加和删除悬停.
This clearly works for mouse events: mouseenter
and mouseleave
(slightly improved versions of mouseover
and mouseout
) are fired, and add and remove the hover.
如果用户实际点击
链接,悬停效果也会被移除.这确保如果用户在 Web 浏览器中按下后退按钮,它会被删除.
If the user actually click
s a link, the hover effect is also removed. This ensure that it is removed if the user presses the back button in the web browser.
这也适用于触摸事件:在 touchstart 时添加了悬停效果.它在 touchend 上'''not''' 被删除.它在 mouseenter
上再次添加,并且由于这不会导致内容更改(它已经添加),所以 click
事件也被触发,并且不需要链接就可以跟随供用户再次点击!
This also works for touch events: on touchstart the hover effect is added. It is '''not''' removed on touchend. It is added again on mouseenter
, and since this causes no content changes (it was already added), the click
event is also fired, and the link is followed without the need for the user to click again!
浏览器在 touchstart
事件和 click
之间的 300 毫秒延迟实际上得到了很好的利用,因为在这很短的时间内会显示悬停效果.
The 300ms delay that a browser has between a touchstart
event and click
is actually put in good use because the hover effect will be shown during this short time.
如果用户决定取消点击,手指的移动将照常执行.通常,这是一个问题,因为没有触发 mouseleave
事件,并且悬停效果仍然存在.值得庆幸的是,可以通过移除 touchmove
上的悬停效果轻松解决此问题.
If the user decides to cancel the click, a move of the finger will do so just as normal. Normally, this is a problem since no mouseleave
event is fired, and the hover effect remains in place. Thankfully, this can easily be fixed by removing the hover effect on touchmove
.
就是这样!
请注意,可以消除 300 毫秒的延迟,例如使用 FastClick 库,但这超出了这个问题的范围.
Note that it is possible to remove the 300ms delay, for example using the FastClick library, but this is out of scope for this question.
我发现以下替代方案存在以下问题:
I've found the following problems with the following alternatives:
touchend
中模拟点击事件: 这将错误地跟随链接,即使用户只想滚动或缩放,而没有实际点击链接的意图.touchend
中设置一个变量,该变量用作后续鼠标事件中的 if 条件,以防止此时状态发生变化及时.变量在点击事件中被重置.请参阅此页面上的 Walter Roman 的回答.如果您真的不希望在触摸界面上产生悬停效果,这是一个不错的解决方案.不幸的是,如果 touchend
因其他原因被触发并且没有触发点击事件(例如用户滚动或缩放),并且随后尝试用鼠标跟随链接(即在具有鼠标和触摸界面的设备).touchend
: This will incorrectly follow the link, even if the user only wanted to scroll or zoom, without the intention of actually clicking the link.touchend
that is used as a if-condition in subsequent mouse events to prevents state changes at that point in time. The variable is reset in the click event. See Walter Roman's answer on this page. This is a decent solution if you really don't want a hover effect on touch interfaces. Unfortunately, this does not work if a touchend
is fired for another reason and no click event is fired (e.g. the user scrolled or zoomed), and is subsequently trying to following the link with a mouse (i.e on a device with both mouse and touch interface).mouseover
或 mousemove
事件期间内容更改后不会触发更多事件.mouseover
or mousemove
event.这篇关于在移动浏览器上禁用悬停效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!