更新时间:2021-12-01 07:47:28
我从您的问题中得知,您的悬停效果会改变您页面的内容.在这种情况下,我的建议是:
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.