在移动浏览器上禁用悬停效果

Posted

技术标签:

【中文标题】在移动浏览器上禁用悬停效果【英文标题】:Disable hover effects on mobile browsers 【发布时间】:2012-01-07 15:45:45 【问题描述】:

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

问题是,当我在平板电脑上点击某物时,浏览器显然有某种“隐形鼠标光标”,它会移动到我点击的位置,然后将其留在那里——所以我刚刚点击的东西会亮起在我点击其他东西之前,会出现悬停效果。

如何在使用鼠标时获得悬停效果,但在使用触摸屏时抑制它们?

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

我已经尝试挂钩touchstarttouchmovetouchend 事件并在所有这些事件上调用preventDefault(),这确实有时会抑制“隐形鼠标光标”;但是如果我在两个不同的元素之间来回快速点击,点击几下后它会开始移动“鼠标光标”并点亮悬停效果——就像我的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>

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

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

【问题讨论】:

@Blender,你读过这个问题吗?我已经解释了为什么用户代理嗅探是一个糟糕的选择。 嗨,乔,你找到解决办法了吗? 我正在寻找这种问题,很高兴找到它! 另请参阅此问题,该问题涉及在任何支持触摸的设备上禁用悬停,而不仅仅是移动设备:***.com/questions/23885255/… 【参考方案1】:

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

touchstartmouseenter 上添加悬停效果。 移除mouseleavetouchmoveclick 上的悬停效果。

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

背景

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

    touchstart touchmove touchend 300 毫秒延迟,浏览器确保这是单击,而不是双击 mouseover mouseenter 注意:如果mouseovermouseentermousemove 事件更改了页面内容,则永远不会触发以下事件。 mousemove mousedown mouseup click

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

更糟糕的是,如果鼠标悬停事件更改了页面内容,则永远不会触发 click 事件,如 Safari Web Content Guide - Handling Events 中所述,尤其是 One-Finger Events 中的图 6.4。 “内容更改”究竟是什么,将取决于浏览器和版本。我发现对于 ios 7.0,背景颜色的更改不是(或不再是?)内容更改。

解决方案说明

回顾一下:

touchstartmouseenter 上添加悬停效果。 移除mouseleavetouchmoveclick 上的悬停效果。

请注意,touchend 上没有任何操作!

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

如果用户实际上clicks 链接,悬停效果也会被移除。这确保如果用户在 Web 浏览器中按下后退按钮,它会被删除。

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

浏览器在touchstart 事件和click 之间的 300 毫秒延迟实际上得到了很好的利用,因为悬停效果会在这很短的时间内显示出来。

如果用户决定取消点击,手指的移动将照常执行。通常,这是一个问题,因为没有触发 mouseleave 事件,并且悬停效果仍然存在。值得庆幸的是,可以通过移除 touchmove 上的悬停效果轻松解决此问题。

就是这样!

请注意,可以删除 300 毫秒的延迟,例如使用 FastClick library,但这超出了本问题的范围。

替代解决方案

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

浏览器检测:极易出错。假设设备具有鼠标或触控功能,而当触控显示器激增时,两者的结合将变得越来越普遍。 CSS 媒体检测: 我所知道的唯一纯 CSS 解决方案。仍然容易出错,并且仍然假定设备具有鼠标或触摸功能,而两者都是可能的。 模拟touchend 中的点击事件:这将错误地跟随链接,即使用户只想滚动或缩放,而没有实际点击链接的意图。 使用变量来抑制鼠标事件: 这会在touchend 中设置一个变量,该变量用作后续鼠标事件中的 if 条件,以防止在该时间点发生状态更改。变量在点击事件中被重置。请参阅此页面上的 Walter Roman 的回答。如果您真的不希望在触摸界面上产生悬停效果,这是一个不错的解决方案。不幸的是,如果touchend 因其他原因被触发并且没有触发点击事件(例如用户滚动或缩放),并且随后尝试用鼠标跟随链接(即在同时使用鼠标的设备上),这不起作用和触摸界面)。

进一步阅读

http://jsfiddle.net/macfreek/24Z5M/。在此沙盒中自行测试上述解决方案。 http://www.macfreek.nl/memory/Touch_and_mouse_with_hover_effects_in_a_web_browser。相同的答案,但有更多背景知识。 https://www.html5rocks.com/en/mobile/touchandmouse/。 html5rocks.com 上关于触摸和鼠标的一般性背景文章。 https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html。 Safari Web 内容指南 - 处理事件。具体参见图 6.4,它解释了在 mouseovermousemove 事件期间内容更改后不会触发更多事件。

【讨论】:

不错的答案。我用你的小提琴开始创建我自己的解决方案。然而,有时需要触摸端。 (当 touchmove 没有运行时——即当用户离开文档本身时......) 很好的答案,但在大多数情况下,我建议在大多数情况下使用touchend 而不是 touchstart,以避免在用户尝试滑动时立即触发操作-向上或向下滚动页面。仍然会发生,但不太可能分散注意力或混淆(假设它是无害的,例如显示标签,而不是用户需要知道的事情)【参考方案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 应用它们,那么您可以专门绑定到鼠标事件,和/或再次,您可以仅根据屏幕大小做出一些假设,其中最坏的情况是“问题”是一些使用鼠标的用户错过了悬停效果。

【讨论】:

我只想为鼠标事件添加悬停效果。但是触摸事件模拟鼠标事件。如果我挂钩触摸事件并调用preventDefault(),有时会抑制鼠标事件,但正如我在问题中所说,它不可靠。 对于媒体查询,当Windows 8 出现并且PC 有触摸屏鼠标时会发生什么?如果用户用鼠标悬停,他们会看到鼠标光标,我想要悬停效果;如果他们用触摸屏点击,我不想要悬停效果。但是我还没有找到可靠的方法来检测触摸和鼠标之间的区别。 好吧,一旦浏览器开发人员在触摸和鼠标设备上拥有更多用户,他们可能会更有动力使检测更加一致。但现在?我会根据屏幕尺寸进行猜测,但其他答案中还有其他建议。抱歉,我无法提供更多帮助。【参考方案3】:

我为最近的一个项目编写了以下 JS,该项目是一个桌面/移动/平板电脑网站,具有不应在触摸时出现的悬停效果。

下面的mobileNoHoverState 模块有一个变量preventMouseover(最初声明为false),当用户在元素$target 上触发touchstart 事件时,该变量设置为true

然后,每当触发 mouseover 事件时,preventMouseover 就会被设置回 false,如果用户同时使用他们的触摸屏和鼠标,这允许网站按预期工作。

我们知道mouseovertouchstart 之后被触发,因为它们在init 中声明的顺序。

var mobileNoHoverState = function() 

    var hoverClass = 'hover',
        $target = $(".foo"), 
        preventMouseover = false;

    function forTouchstart() 
        preventMouseover = true;
    

    function forMouseover() 
        if (preventMouseover === false) 
            $(this).addClass(hoverClass);
         else 
            preventMouseover = false;
        
    

    function forMouseout() 
        $(this).removeClass(hoverClass);
    

    function init() 
        $target.on(
            touchstart  : forTouchstart,
            mouseover   : forMouseover,
            mouseout    : forMouseout
        );                
    

    return 
        init: init
    ;
();

该模块随后被进一步实例化:

mobileNoHoverState.init();

【讨论】:

"每次触发 mouseover 事件时,preventMouseover 都会被设置回 true,这样如果用户同时使用触摸屏和鼠标,网站就可以按预期工作。" - 你的代码没有这样做。我错过了什么吗? @Redtopia 感谢您的提醒!我已经用遗漏的代码更新了答案。 函数声明后不需要分号 @nacholibre 正确使用分号【参考方案4】:

我自己真的想要一个纯粹的css 解决方案,因为围绕我的所有观点散布一个重量级的 javascript 解决方案似乎是一个不愉快的选择。终于找到了@media.hover查询,它可以检测“主要输入机制是否允许用户将鼠标悬停在元素上”。这避免了触摸设备,其中“悬停”更多的是模拟动作而不是输入设备的直接功能。

例如,如果我有一个链接:

<a href="/" class="link">Home</a>

然后我可以安全地将其样式设置为仅:hover,当设备使用此css 轻松支持它时:

@media (hover: hover) 
  .link:hover  /* hover styles */ 

虽然大多数现代浏览器都支持交互媒体功能查询,但一些流行的浏览器such as IE and Firefox 不支持。就我而言,这很好用,因为我只打算在桌面上支持 Chrome,在移动设备上支持 Chrome 和 Safari。

【讨论】:

不错的解决方案,当您在 Chrome 开发工具中模拟设备时似乎可以工作。但它仍然不适用于 Chrome android :-( 我认为这是最方便和正确的解决方案。希望它很快就会被添加到 W3C 标准中。【参考方案5】:

我的解决方案是在 HTML 标签中添加 hover-active css 类, 并在所有 CSS 选择器的开头使用 :hover 并在第一个 touchstart 事件中删除该类。

http://codepen.io/Bnaya/pen/EoJlb

JS:

(function () 
    'use strict';

    if (!('addEventListener' in window)) 
        return;
    

    var htmlElement = document.querySelector('html');

    function touchStart () 
        document.querySelector('html').classList.remove('hover-active');

        htmlElement.removeEventListener('touchstart', touchStart);
    

    htmlElement.addEventListener('touchstart', touchStart);
());

HTML:

<html class="hover-active">

CSS:

.hover-active .mybutton:hover 
    box-shadow: 1px 1px 1px #000;

【讨论】:

您可以测试'ontouchstart' in window,而不是监听触摸事件。例如if ('ontouchstart' in window) document.querySelector('html').classList.remove('hover-active'); @YuvalA。我等待触摸事件的原因是有设备支持指针和触摸,并且用户正在使用指针,我不想删除悬停。用户可能会先使用触摸,然后再使用指针,但我对此没什么可做的【参考方案6】:

我为解决同样的问题所做的是进行特征检测(我使用类似 this code 的东西),查看是否定义了 onTouchMove,如果是,我将 css 类“touchMode”添加到正文中,否则我添加“desktopMode”。

然后,每次某些样式效果仅适用于触摸设备或仅适用于桌面时,css 规则都会以适当的类为前缀:

.desktopMode .someClass:hover color: red 
.touchMode .mainDiv  width: 100%; margin: 0; /*etc.*/ 

编辑:这个策略当然会在你的 css 中添加一些额外的字符,所以如果你关心 css 的大小,你可以搜索 touchMode 和 desktopMode 定义并将它们放入不同的文件中,因此您可以为每种设备类型提供优化的 css;或者您可以在开始生产之前将类名更改为更短的名称。

【讨论】:

【参考方案7】:

是的,我遇到了类似的问题,但设法通过媒体查询和简单的 CSS 解决了它。我确定我在这里违反了一些规则,但它对我有用。

我基本上必须采用某人制作的大型应用程序,并使其具有响应性。他们使用 jQueryUI,并要求我不要篡改他们的任何 jQuery,所以我只能单独使用 CSS。

当我在触摸屏模式下按下他们的一个按钮时,悬停效果会在按钮的操作生效之前触发一秒钟。这是我修复它的方法。

@media only screen and (max-width:1024px) 

       #buttonOne
            height: 44px;
        


        #buttonOne:hover
            display:none;
        
   

【讨论】:

【参考方案8】:

在我的项目中,我们使用https://www.npmjs.com/package/postcss-hover-prefix 和https://modernizr.com/ 解决了这个问题 首先,我们使用postcss-hover-prefix 对输出的 css 文件进行后处理。它为所有 css hover 规则添加了 .no-touch

const fs = require("fs");
const postcss = require("postcss");
const hoverPrfx = require("postcss-hover-prefix");

var css = fs.readFileSync(cssFileName, "utf8").toString();
postcss()
   .use(hoverPrfx("no-touch"))
   .process(css)
   .then((result) => 
      fs.writeFileSync(cssFileName, result);
   );

css

a.text-primary:hover 
  color: #62686d;

变成

.no-touch a.text-primary:hover 
  color: #62686d;

在运行时Modernizr 自动将 css 类添加到 html 标记中,如下所示

<html class="wpfe-full-height js flexbox flexboxlegacy canvas canvastext webgl 
  no-touch 
  geolocation postmessage websqldatabase indexeddb hashchange
  history draganddrop websockets rgba hsla multiplebgs backgroundsize borderimage
  borderradius boxshadow textshadow opacity cssanimations csscolumns cssgradients
  cs-s-reflections csstransforms csstransforms3d csstransitions fontface
  generatedcontent video audio localstorage sessionstorage webworkers
  applicationcache svg inlinesvg smil svgclippaths websocketsbinary">

这样的 css plus Modernizr 后处理禁用了触控设备的悬停并启用了其他设备。事实上,这种方法受到 Bootstrap 4 的启发,它们如何解决相同的问题:https://v4-alpha.getbootstrap.com/getting-started/browsers-devices/#sticky-hoverfocus-on-mobile

【讨论】:

【参考方案9】:

您可以在触摸触摸屏上的元素时触发mouseLeave 事件。这是所有&lt;a&gt;标签的解决方案:

function removeHover() 
    var anchors = document.getElementsByTagName('a');
    for(i=0; i<anchors.length; i++) 
        anchors[i].addEventListener('touchstart', function(e)
            $('a').mouseleave();
        , false);
    

【讨论】:

JSHint 说“不要在循环中创建函数”。 这是一个黑客。它不是可被视为良好实践的可重用代码。 @NetOperatorWibby 好吧,发布不能被视为良好实践的代码并没有真正的帮助。这就像在刀伤上贴创可贴一样。【参考方案10】:

我找到了 2 个问题的解决方案,这意味着您使用modernizr 或其他东西检测触摸并在 html 元素上设置触摸类。

这很好,但不是 supported 很好:

html.touch *:hover 
    all:unset!important;

不过这个有很好的support

html.touch *:hover 
    pointer-events: none !important;

对我来说完美无瑕,它使所有悬停效果就像当您触摸按钮时它会亮起但最终不会像鼠标事件的初始悬停效果那样出现错误。

检测来自非触摸设备的触摸我认为modernizr 做得最好:

https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touchevents.js

编辑

我找到了一个更好更简单的解决方案

How to determine if the client is a touch device

【讨论】:

【参考方案11】:

查看您的 CSS 可能会有所帮助,因为这听起来是一个相当奇怪的问题。但无论如何,如果它正在发生并且其他一切都很好,您可以尝试将悬停效果转移到 javascript(您也可以使用 jquery)。 简单地说,绑定到 mouseover 或更好的 mouseenter 事件,并在事件触发时点亮您的元素。

在此处查看最后一个示例:http://api.jquery.com/mouseover/,您可以在事件触发时使用类似于日志的内容并从那里获取!

【讨论】:

CSS 没什么特别的;看我的编辑。我已经尝试过mouseenter;没有骰子。点击会移动“隐形鼠标光标”,因此它会触发mouseentermousemove(当您点击其他位置时会触发mouseleave)。【参考方案12】:

如果您乐于使用 JavaScript,那么您可以在您的页面中使用 Modernizr。当页面加载时,非触摸屏浏览器会将类“.no-touch”添加到 html 标签中,但对于触摸屏浏览器,html 标签会将类“.touch”添加到 html 标签中.

那么在决定添加 mouseenter 和 mouseleave 侦听器之前,只需检查 html 标记是否具有 no-touch 类。

if($('html').hasClass('no-touch'))
    $('.box').on("mouseenter", function(event)
            $(this).css('background-color','#0000ff')
    );
    $('.box').on("mouseleave", function(event)
            $(this).css('background-color','')
    );

对于触摸屏设备,事件将没有侦听器,因此您在点击时不会获得悬停效果。

【讨论】:

当它可以用 css 完成时不要使用 javascript(jquery) 它浪费计算机电源 更简单的是,在您的 CSS 中,您可以为 .touch.no-touch 定义单独的规则。要与 Modernizer 一起在 CSS 中重写您的答案,html.no-touch .box:hover background-color: "#0000ff" 并且不为 html.touch .box:hover 定义任何东西应该可以解决问题,因为 OP 只是试图避免移动 :hovers。【参考方案13】:

在我最近做的一个项目中,我用 jQuery 的委托事件功能解决了这个问题。它使用 jQuery 选择器查找某些元素,并在鼠标悬停在元素上时向这些元素添加/删除 CSS 类。就我能够测试它而言,它似乎运行良好,其中包括在运行 Windows 8 的触控笔记本上的 IE10。

$(document).ready(
    function()
    
        // insert your own selector here: maybe '.hoverable'?
        var selector = 'button, .hotspot';

        $('body')
            .on('mouseover', selector, function() $(this).addClass('mouseover');    )
            .on('mouseout',  selector, function() $(this).removeClass('mouseover'); )
            .on('click',     selector, function() $(this).removeClass('mouseover'); );
    
);

编辑: 当然,此解决方案确实需要您更改 CSS 以删除“:hover”选择器,并提前考虑您希望哪些元素可以“悬停” "。

如果你的页面上有很多元素(比如几千个),它可能会有点慢,因为这个解决方案会在页面中的 所有元素 上捕获三种类型的事件,然后如果选择器匹配,它会做它的事情。我将 CSS 类命名为“mouseover”而不是“hover”,因为我不希望任何 CSS 读者在我写“.hover”的地方阅读“:hover”。

【讨论】:

【参考方案14】:

这是我的解决方案:http://jsfiddle.net/agamemnus/g56aw709/-- 下面的代码。

所有需要做的就是将他们的“:hover”转换为“.hover”......就是这样!这与其他的最大区别在于,这也适用于非奇异元素选择器,例如.my_class &gt; *:hover

handle_css_hover_effects ()

function handle_css_hover_effects (init) 
 var init = init || 
 var handle_touch_events = init.handle_touch_events || true
 var handle_mouse_events = init.handle_mouse_events || true
 var hover_class         = init.hover_class         || "hover"
 var delay_preferences   = init.delay_preferences   || touch: add: 500, remove: 500
 function default_handler (curobj, input_type, op) 
  var hovered_element_selector = "*" + ((op == "add") ? ":" : ("." + hover_class))
  var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll(hovered_element_selector))
  var modified_list = []
  while (true) 
   if ((curobj == null) || (curobj == document.documentElement)) break
   if (hovered_elements.indexOf(curobj) != -1) modified_list.push (curobj)
   curobj = curobj.parentNode
  
  function do_hover_change () modified_list.forEach (function (curobj) curobj.classList[op](hover_class))
  if ((!delay_preferences[input_type]) || (!delay_preferences[input_type][op])) 
   do_hover_change ()
   else 
   setTimeout (do_hover_change, delay_preferences[input_type][op])
  
 

 if (handle_mouse_events) 
  document.body.addEventListener ('mouseover' , function (evt) var curobj = evt.target; default_handler (curobj, "mouse", "add"))
  document.body.addEventListener ('mouseout'  , function (evt) var curobj = evt.target; default_handler (curobj, "mouse", "remove"))
  document.body.addEventListener ('click'     , function (evt) var curobj = evt.target; default_handler (curobj, "mouse", "remove"))
 

 if (handle_touch_events) 
  document.body.addEventListener ('touchstart', function (evt) var curobj = evt.target; default_handler (curobj, "touch", "add"))
  document.body.addEventListener ('touchend'  , function (evt) var curobj = evt.target; default_handler (curobj, "touch", "remove"))
  document.body.addEventListener ('touchmove',  function (evt) 
   var curobj = evt.target
   var hovered_elements = Array.prototype.slice.call(document.body.querySelectorAll("*:hover"))
   var lastobj = null
   evt = evt.changedTouches[0]
   var elements_at_point = get_elements_at_point (evt.pageX, evt.pageY)
   // Get the last element that isn't at the current point but is still hovered over, and remove only its hover attribute.
   while (true) 
    if ((curobj == null) || (curobj == document.documentElement)) break
    if ((hovered_elements.indexOf(curobj) != -1) && (elements_at_point.indexOf(curobj) == -1)) lastobj = curobj
    curobj = curobj.parentNode
   
   if (lastobj == null) return
   if ((!delay_preferences.touch) || (!delay_preferences.touch.remove)) 
    lastobj.classList.remove(hover_class)
    else 
    setTimeout (function () lastobj.classList.remove(hover_class), delay_preferences.touch.remove)
   

   function get_elements_at_point (x, y) 
    var el_list = [], pe_list = []
    while (true) 
     var curobj = document.elementFromPoint(x, y)
     if ((curobj == null) || (curobj == document.documentElement)) break
     el_list.push (curobj); pe_list.push (curobj.style.pointerEvents)
     curobj.style.pointerEvents = "none"
    
    el_list.forEach (function (current_element, i) current_element.style.pointerEvents = pe_list[i])
    return el_list
   
  )
 

【讨论】:

【参考方案15】:

在您的页面上包含 Modernizr 并设置悬停状态,如下所示:

html.no-touchevents .box:hover 
    background: blue;

【讨论】:

【参考方案16】:

你好,来自未来的人,你可能想要使用pointer 和/或hover 媒体查询。 handheld 媒体查询已被弃用。

/* device is using a mouse or similar */
@media (pointer: fine) 
  a:hover 
    background: red;
  

【讨论】:

【参考方案17】:

.services-list .fa 
    transition: 0.5s;
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
    color: blue;

/* For me, @media query is the easiest way for disabling hover on mobile devices */
@media only screen and (min-width: 981px) 
    .services-list .fa:hover 
        color: #faa152;
        transition: 0.5s;
        -webkit-transform: rotate(360deg);
        transform: rotate(360deg);
    

/* You can actiate hover on mobile with :active */
.services-list .fa:active 
    color: #faa152;
    transition: 0.5s;
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);

.services-list .fa-car 
  font-size:20px;
  margin-right:15px;

.services-list .fa-user 
  font-size:48px;
  margin-right:15px;

.services-list .fa-mobile 
  font-size:60px;
<head>
<title>Hover effects on mobile browsers</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>

<body>
<div class="services-list">
<i class="fa fa-car"></i>
<i class="fa fa-user"></i>
<i class="fa fa-mobile"></i>
</div>
</body>

例如:https://jsfiddle.net/lesac4/jg9f4c5r/8/

【讨论】:

【参考方案18】:

你可以使用js。它应该按预期工作。

function myFunction()
    var x = document.getElementById("DIV");
  x.style.backgroundColor="red";
  x.style.cursor="pointer";
  x.style.color="white"

function my2Function()
    var x = document.getElementById("DIV");
  x.style.backgroundColor="white";
  x.style.color="red"
.mydiv 
  background-color: white;
  color: red;
<div class = "mydiv" id="DIV" onmouseover="myFunction()" onmouseleave="my2Function()">
  hi
</div>

【讨论】:

【参考方案19】:

这里我的问题已通过使用修复(React js 中的鼠标输入和触摸相关问题)

onMouseEnter=() =&gt; addHeaderClassName() onMouseLeave=() =&gt; removeHeaderClassName() onFocus=() =&gt; addHeaderClassName() onBlur=() =&gt; removeHeaderClassName()

上面提到的“onMouseEnter 和 onMouseLeave”适用于大型设备,例如可以检测到鼠标事件的桌面设备,而“onFocus 和 onBlur”适用于可以检测触摸的平板电脑和移动设备等小型设备。

【讨论】:

【参考方案20】:

这里我的问题已通过使用修复(React js 中的鼠标输入和触摸相关问题)

onMouseEnter=() => addHeaderClassName() onMouseLeave=() => removeHeaderClassName() onFocus=() => addHeaderClassName() onBlur=() => removeHeaderClassName()

上面提到的“onMouseEnter 和 onMouseLeave”适用于大型设备,例如可以检测到鼠标事件的桌面设备,而“onFocus 和 onBlur”适用于可以检测触摸的平板电脑和移动设备等小型设备。

【讨论】:

【参考方案21】:

试试这个简单的 2019 jquery 解决方案,虽然它已经有一段时间了;

    将此插件添加到头部:

    src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"

    将此添加到 js:

    $("*").on("touchend", function(e) $(this).focus(); ); //applies to all elements

    一些建议的变化是:

    $(":input, :checkbox,").on("touchend", function(e) (this).focus);); //specify elements
    
    $("*").on("click, touchend", function(e)  $(this).focus(); );  //include click event`
    
    css: body  cursor: pointer;  //touch anywhere to end a focus`
    

注意事项

在 bootstrap.js 之前放置插件(如果适用)以避免影响工具提示 仅在 iphone XR ios 12.1.12 和 ipad 3 ios 9.3.5 上使用 Safari 或 Chrome 进行测试。

参考资料:

https://code.jquery.com/ui/

https://api.jquery.com/category/selectors/jquery-selector-extensions/

【讨论】:

以上是关于在移动浏览器上禁用悬停效果的主要内容,如果未能解决你的问题,请参考以下文章

由于悬停时的转换/缩放,在移动设备上难以滚动

在移动设备上禁用粘性导航

在移动设备和平板设备上禁用悬停

首先引导手机?为啥悬停仍然适用于移动设备?如何禁用悬停?

UC 浏览器中的对齐问题和图像悬停效果问题

移动设备上的悬停效果