在移动浏览器上停用悬停效果 [英] Disable hover effects on mobile browsers

查看:176
本文介绍了在移动浏览器上停用悬停效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



问题是,当我点击平板电脑上的某些东西时,浏览器显然有某种隐形鼠标光标它移动到我点击的位置,然后将它放在那里 - 所以我刚刚点击的东西点亮了悬停效果,直到我点击其他东西。



我在使用鼠标时如何获得悬停效果,但在使用触摸屏时会将其抑制?

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



我已经尝试将 touchstart touchmove touchend 事件并调用 preventDefault ),它们在某些时候抑制了不可见的鼠标光标;但是如果我在两个不同的元素之间来回切换,在几次点击之后,它将开始移动鼠标光标并照亮悬停效果 - 就像我的 preventDefault 并不总是很荣幸。除非有必要,否则我不会告诉你任何细节 - 我甚至不确定这是正确的方法;如果有人有一个更简单的修复,我全部耳光。






编辑:使用bog标准的CSS :hover 进行转换,但是这里有一个快速转载作为参考。

 <风格> 
.box {border:1px纯黑色;宽度:150px; height:150px; }
.box:hover {background:blue; }
< / style>
< div class =box>< / div>
< div class =box>< / div>

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



我也发布了一个上面提供了这里的示例,并且还挂钩了jQuery的鼠标事件。您可以使用它来查看tap事件也会触发 mouseenter mousemove mouseleave

解决方案

我从你的问题中看出,你的悬停效果改变了你的页面内容。在这种情况下,我的建议是:


  • touchstart mouseenter

  • 移除 mouseleave touchmove 点击



另外,您可以编辑您的页面,以确保没有内容更改。



背景



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


  1. touchstart

  2. touchmove

  3. touchend

  4. 300ms的延迟,浏览器确保这是一次点击,而不是一次双击点击

  5. mouseover

  6. mouseenter


    • 注意:如果 mouseover mouseenter mousemove 事件会更改页面内容,因此以下事件永远不会被触发。


    • mousemove

    • mousedown

    • mouseup
    • 点击

只要告知网页浏览器跳过鼠标事件。

更糟糕的是,如果一个mouseover事件改变了页面内容,click事件永远不会被触发,正如 Safari网页内容指南 - 处理活动,in One-Finger Events 中的特定图6.4。究竟什么是内容变化,将取决于浏览器和版本。我发现对于iOS 7.0,背景颜色的变化不会(或不再)变更内容。



解决方案说明



总结:


  • touchstart 和 mouseenter

  • 移除 mouseleave touchmove 点击



请注意,对于 touchend



没有任何操作,这对于鼠标事件很明显: mouseenter mouseleave (稍微改进版本的 mouseover mouseout



如果用户真的点击,则会触发并添加并移除悬停。 > sa链接,悬停效果也被删除。这可确保在用户按下Web浏览器中的后退按钮时将其删除。



这也适用于触摸事件:在touchstart上添加了悬停效果。它是''''不'''删除touchend。它再次添加在 mouseenter 上,并且由于这不会导致内容更改(它已经添加),所以点击事件也被触发,并且链接被遵循,而不需要用户再次点击!



浏览器在 touchstart之间延迟300ms 事件和点击实际上是很有用的,因为悬停效果会在短时间内显示。



如果用户决定取消点击,手指的移动将如常进行。通常情况下,这是一个问题,因为没有 mouseleave 事件被触发,并且悬停效果保持不变。谢天谢地,这可以通过消除 touchmove 上的悬停效应来解决。



请注意,可以移除300毫秒的延迟,例如使用 FastClick图书馆,但这超出了这个问题的范围。



另类解决方案



我们发现了以下问题:


  • 浏览器检测:非常容易出错。假设设备具有鼠标或触控,而两者的组合会在触控显示器增加时变得越来越普遍。

  • CSS媒体检测:唯一我知道的仅限CSS的解决方案。

  • 模拟 touchend 中的点击事件,可以避免错误,并且仍然假设设备具有鼠标或触摸功能。 code>:即使用户只想滚动或放大,也不会实际点击链接,这将错误地跟随链接。

  • 使用一个变量来抑制鼠标事件: touchend 中设置一个变量,在随后的鼠标事件中用作if条件来防止那个状态发生变化时间点。该变量在点击事件中被重置。请参阅Walter Roman在此页面上的回答。如果你不想在触摸界面上产生悬停效果,这是一个体面的解决方案。不幸的是,如果因为其他原因触发 touchend 并且没有触发点击事件(例如用户滚动或缩放)并且随后试图跟随链接使用鼠标(即在具有鼠标和触摸界面的设备上)。

    $ b $ h1>进一步阅读


    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.

    How can I get the hover effects when I'm using the mouse, but suppress them when I'm using the touchscreen?

    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.

    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.


    Edit: 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.

    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:

    • Add hover effects on touchstart and mouseenter.
    • Remove hover effects on mouseleave, touchmove and click.

    Alternatively, you can edit your page that there is no content change.

    Background

    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):

    1. touchstart
    2. touchmove
    3. touchend
    4. 300ms delay, where the browser makes sure this is a single tap, not a double tap
    5. mouseover
    6. mouseenter
      • Note: If a mouseover, mouseenter or mousemove event changes the page content, the following events are never fired.
    7. mousemove
    8. mousedown
    9. mouseup
    10. click

    It does not seem possible to simply tell the webbrowser to skip the mouse events.

    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.

    Solution Explained

    To recap:

    • Add hover effects on touchstart and mouseenter.
    • Remove hover effects on mouseleave, touchmove and click.

    Note that there is no action on touchend!

    This clearly works for mouse events: mouseenter and mouseleave (slightly improved versions of mouseover and mouseout) are fired, and add and remove the hover.

    If the user actually clicks 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.

    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!

    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.

    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.

    That's it!

    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.

    Alternative Solutions

    I've found the following problems with the following alternatives:

    • browser detection: Extremely prone to errors. Assumes that a device has either mouse or touch, while a combination of both will become more and more common when touch displays prolifirate.
    • CSS media detection: The only CSS-only solution I'm aware of. Still prone to errors, and still assumes that a device has either mouse or touch, while both are possible.
    • Emulate the click event in 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.
    • Use a variable to suppress mouse events: This set a variable in 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).

    Further Reading

    这篇关于在移动浏览器上停用悬停效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆