如何防止触摸设备上按钮的粘滞悬停效果


144

我创建了一个带有始终可见的上一个和下一个按钮的轮播。这些按钮处于悬停状态,它们变为蓝色。在诸如iPad的触摸设备上,悬停状态为粘滞状态,因此在点击它后按钮保持蓝色。我不要

  • 我可以为每个按钮添加一个no-hoverontouchend,并使CSS像这样:button:not(.no-hover):hover { background-color: blue; }但这可能会降低性能,并且不能正确处理Chromebook Pixel(具有触摸屏和鼠标)之类的设备。

  • 我可以向中添加一个touchdocumentElement,并使CSS像这样:html:not(.touch) button:hover { background-color: blue; }但是,这在同时带有触摸和鼠标的设备上也无法正常工作。

我更希望删除悬停状态ontouchend。但这似乎是不可能的。聚焦另一个元素不会删除悬停状态。手动点击另一个元素可以,但是我似乎无法在JavaScript中触发它。

我发现的所有解决方案似乎都不完美。有没有完美的解决方案?

Answers:


55

您可以通过从DOM临时删除链接来删除悬停状态。看到http://testbug.handcraft.com/ipad.html


在CSS中,您可以:

:hover {background:red;}

在JS中,您可以:

function fix()
{
    var el = this;
    var par = el.parentNode;
    var next = el.nextSibling;
    par.removeChild(el);
    setTimeout(function() {par.insertBefore(el, next);}, 0)
}

然后在您的HTML中:

<a href="#" ontouchend="this.onclick=fix">test</a>

3
@Chris好点,我更改了示例以在ontouchend事件中设置onclick处理程序。
Sjoerd Visscher 2013年

4
请考虑在您的答案中添加最少的说明性代码。谢谢!stackoverflow.com/help/how-to-answer
2540625年

1
@SjoerdVisscher我将其粘贴。StackOverflow喜欢答案中的代码,因为链接可能会消失。(在这种情况下,它不仅需要单击,还需要查看源代码,并确定所涉及的技术是什么。)
Darren Cook 2014年

2
@KevinBorders是,在某些设备上,删除和重新插入元素之间的时间延迟非常明显。不幸的是,我发现在我的android 4.4设备上没有setTimeout这样做是行不通的。
罗德尼

1
这个想法很有趣,但是我发现它有点生涩,并且在所有触摸设备上均未得到广泛支持。我希望采用基于触摸支持检测和纯CSS的侵入性较小的解决方案,例如stackoverflow.com/a/39787268/885464
Lorenzo Polidori

83

一旦CSS媒体查询4级实现,你就可以做到这一点:

@media (hover: hover) {
    button:hover {
        background-color: blue;
    }
}

或用英语表示:“如果浏览器支持正确/真实/真实/非仿真悬停(例如,具有类似鼠标的主输入设备),则将button悬停时应采用此样式。”

由于到目前为止,“媒体查询级别4”的这一部分仅在最先进的Chrome中实现,因此我编写了一个polyfill来处理这一问题。使用它,您可以将上述未来派CSS转换为:

html.my-true-hover button:hover {
    background-color: blue;
}

(该.no-touch技术的一种变体)然后使用来自同一polyfill的一些客户端JavaScript来检测对悬停的支持,您可以相应地切换my-true-hover该类的存在:

$(document).on('mq4hsChange', function (e) {
    $(document.documentElement).toggleClass('my-true-hover', e.trueHover);
});

谢谢!出于我的目的,大多数浏览器caniuse.com/#search=media%20查询都支持此功能,并且效果很好,谢谢!
ragamufin

3
您需要查看caniuse.com/#feat=css-media-interaction,您会发现Firefox和IE11不支持它:(因此,您需要使用
polyfill

似乎不再支持polyfill(回购已存档),它需要jQuery ...
polyfill amoebe

现在,此功能已在移动浏览器中得到广泛支持,并且像超级按钮一样工作。我认为这应该是公认的答案。
Trevor Burnham

这绝对是最容易实现和最佳答案。适用于Android Mobile和PC上的Firefox。不确定双触摸和鼠标设备。
HalfMens

28

这是一个普遍的问题,没有完美的解决方案。悬停行为对于鼠标很有用,并且大多数情况下对触摸有害。使问题更加复杂的是支持触摸和鼠标(同时,不少!)的设备,例如Chromebook Pixel和Surface。

我发现的最干净的解决方案是仅在不认为该设备支持触摸输入时才启用悬停行为。

var isTouch =  !!("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;

if( !isTouch ){
    // add class which defines hover behavior
}

当然,您在可能支持它的设备上失去了悬停功能。但是,有时悬停影响比链接本身更大,例如,当您悬停元素时,可能要显示菜单。这种方法允许您测试是否存在触摸,并可能有条件地附加其他事件。

我已经在iPhone,iPad,Chromebook Pixel,Surface和各种Android设备上对此进行了测试。我不能保证当将通用USB触摸输入(例如手写笔)添加到混音中时,它将起作用。


1
太棒了,与社区Wiki / Darren Cook的答案不同,这对我有用。
Jannik

1
好答案。这是一个类似的解决方案:stackoverflow.com/a/39787268/885464
Lorenzo Polidori

11

使用Modernizr,您可以将悬停目标特别针对非接触设备:

(注意:这不能在StackOverflow的代码段系统上运行,请检查jsfiddle

/* this one is sticky */
#regular:hover, #regular:active {
  opacity: 0.5;
}

/* this one isn't */
html.no-touch #no-touch:hover, #no-touch:active {
  opacity: 0.5;
}

请注意,:active不需要针对此对象,.no-touch因为它可以在移动设备和台式机上正常工作。


这是IMO的最佳答案,但示例不正确。对于触摸和非触摸设备,它都显示相同的悬停状态。如果标签.no-touch上存在,则仅应应用悬停状态html。否则,此答案将得到我的认可。
morrisbret 2015年

2
问题在于,既然具有触摸屏的启用鼠标的设备无处不在,那么您将不再真正依赖此方法。但是,我看不到有其他另一种方式可以做到这一点……这是一个两难选择
dudewad 2015年

我想做到这一点的一种方法是同时使用Modernizr和诸如mobile-detect.js之类的库,以确保它是手机还是平板电脑。
加文

您是救世主,非常感谢此功能非常适合移动设备
Shivam

8
$("#elementwithhover").click(function() { 
  // code that makes element or parent slide or otherwise move out from under mouse. 

  $(this).clone(true).insertAfter($(this));
  $(this).remove();
});

您可以使用on()代替click()来改善此答案。通过从DOM中删除元素并重新附加它,我失去了点击事件。当我用on重新编写函数时,绑定到元素,然后删除并添加工作。例如:`$('body')。on('click','#elementwithhover',function(){// clone,insertafter,remove}); 如果您做出更改,我会投票赞成。
Will Lanni

如果为true,则clone会保留新的elemenet上的click事件,从而将元素停留在悬停的位置。原始元素将在克隆后从dom中删除。
Verard Sloggett '16年

很棒的兄弟,10x
Kaloyan Stamatov

数小时的搜索修复程序终于得到了解决方案。太感谢了!
phil917

8

4种方式来处理移动粘悬停:这是一种动态添加或删除“ can touch”类基于用户的当前输入类型的文档。它也可以与混合设备一起使用,用户可以在其中进行触摸和鼠标/触控板之间的切换:

<script>

;(function(){
    var isTouch = false //var to indicate current input type (is touch versus no touch) 
    var isTouchTimer 
    var curRootClass = '' //var indicating current document root class ("can-touch" or "")

    function addtouchclass(e){
        clearTimeout(isTouchTimer)
        isTouch = true
        if (curRootClass != 'can-touch'){ //add "can-touch' class if it's not already present
            curRootClass = 'can-touch'
            document.documentElement.classList.add(curRootClass)
        }
        isTouchTimer = setTimeout(function(){isTouch = false}, 500) //maintain "istouch" state for 500ms so removetouchclass doesn't get fired immediately following a touch event
    }

    function removetouchclass(e){
        if (!isTouch && curRootClass == 'can-touch'){ //remove 'can-touch' class if not triggered by a touch event and class is present
            isTouch = false
            curRootClass = ''
            document.documentElement.classList.remove('can-touch')
        }
    }

    document.addEventListener('touchstart', addtouchclass, false) //this event only gets called when input type is touch
    document.addEventListener('mouseover', removetouchclass, false) //this event gets called when input type is everything from touch to mouse/ trackpad
})();

</script>

这是我找到的最佳方法,另外,如果将计时器增加到1000ms,也可以覆盖长按,请参见此处。好东西!
lowtechsun

8

您可以为不支持悬停的设备覆盖悬停效果。喜欢:

.my-thing {
    color: #BADA55;
}

.my-thing:hover {
    color: hotpink;
}

@media (hover: none) {
    .my-thing {
        color: #BADA55;
    }
}

在iOS 12上经过测试和验证

帽子技巧到https://stackoverflow.com/a/50285058/178959指出了这一点。


这是一种更现代的解决方案,不需要任何javascript或DOM操作,具有完整的浏览器支持(IE除外),应该是公认的答案。
funkju

3

我打算发布自己的解决方案,但是检查是否有人已经发布了它,我发现@Rodney几乎做到了。然而,至少在我看来,他错过了使它变得毫无意义的最后一个关键。我的意思是,我也进行了相同的.fakeHover类添加/删除mouseenter以及mouseleave事件检测,但是就其本身而言,其行为几乎与“正版”一样:hover。我的意思是:当您点击表中的元素时,它不会检测到您已经“离开”了该元素-因此保持了“ fakehover”状态。

我所做的也只是在听click,所以,当我“点击”按钮时,我会手动触发一个mouseleave

Si,这是我的最终代码:

.fakeHover {
    background-color: blue;
}


$(document).on('mouseenter', 'button.myButton',function(){
    $(this).addClass('fakeHover');
});

$(document).on('mouseleave', 'button.myButton',function(){
    $(this).removeClass('fakeHover');
});

$(document).on('button.myButton, 'click', function(){
    $(this).mouseleave();
});

这样,hover当您将鼠标悬停在按钮上时,使用鼠标时就可以保持通常的功能。好吧,几乎所有内容:唯一的缺点是,用鼠标单击按钮之后,它就不会处于hover状态。就像您单击并快速将指针移出按钮一样。但就我而言,我可以接受。


2

到目前为止,在研究了其余答案之后,这就是我想出的。它应该能够支持纯触摸,纯鼠标或混合用户。

为悬浮效果创建一个单独的悬浮类。默认情况下,将此悬停类添加到我们的按钮中。

我们不想从一开始就检测到触摸支持并禁用所有悬停效果。就像其他人提到的那样,混合设备正在普及。人们可能有触摸支持,但想要使用鼠标,反之亦然。因此,仅在用户实际触摸按钮时才删除悬停类。

下一个问题是,如果用户想在触摸按钮后返回使用鼠标该怎么办?为了解决这个问题,我们需要找到一个适当的时机来添加我们已删除的悬停类。

但是,由于悬停状态仍处于活动状态,因此我们无法在删除后立即将其重新添加。我们可能也不想破坏并重新创建整个按钮。

因此,我想到了使用繁忙等待算法(使用setInterval)来检查悬停状态。一旦停用了悬停状态,我们就可以添加回悬停类并停止忙碌等待,使我们回到用户可以使用鼠标或触摸的原始状态。

我知道繁忙的等待不是很好,但是我不确定是否有合适的活动。我已经考虑过在mouseleave事件中添加它,但是它不是很可靠。例如,当触摸按钮后弹出警报时,鼠标位置会移动,但不会触发mouseleave事件。

var button = document.getElementById('myButton');

button.ontouchstart = function(e) {
  console.log('ontouchstart');
  $('.button').removeClass('button-hover');
  startIntervalToResetHover();
};

button.onclick = function(e) {
  console.log('onclick');
}

var intervalId;

function startIntervalToResetHover() {
  // Clear the previous one, if any.
  if (intervalId) {
    clearInterval(intervalId);
  }
  
  intervalId = setInterval(function() {
    // Stop if the hover class already exists.
    if ($('.button').hasClass('button-hover')) {
      clearInterval(intervalId);
      intervalId = null;
      return;
    }
    
    // Checking of hover state from 
    // http://stackoverflow.com/a/8981521/2669960.
    var isHovered = !!$('.button').filter(function() {
      return $(this).is(":hover");
    }).length;
    
    if (isHovered) {
      console.log('Hover state is active');
    } else {
      console.log('Hover state is inactive');
      $('.button').addClass('button-hover');
      console.log('Added back the button-hover class');
      
      clearInterval(intervalId);
      intervalId = null;
    }
  }, 1000);
}
.button {
  color: green;
  border: none;
}

.button-hover:hover {
  background: yellow;
  border: none;
}

.button:active {
  border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id='myButton' class='button button-hover'>Hello</button>

编辑:我尝试过的另一种方法是e.preventDefault()在ontouchstart或ontouchend内调用。似乎在触摸按钮时会停止悬停效果,但也会停止按钮单击动画并阻止在触摸按钮时调用onclick函数,因此您必须在ontouchstart或ontouchend处理程序中手动调用它们。不是一个很干净的解决方案。


1

这对我很有帮助: 链接

function hoverTouchUnstick() {
    // Check if the device supports touch events
    if('ontouchstart' in document.documentElement) {
        // Loop through each stylesheet
        for(var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
            var sheet = document.styleSheets[sheetI];
            // Verify if cssRules exists in sheet
            if(sheet.cssRules) {
                // Loop through each rule in sheet
                for(var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
                    var rule = sheet.cssRules[ruleI];
                    // Verify rule has selector text
                    if(rule.selectorText) {
                        // Replace hover psuedo-class with active psuedo-class
                        rule.selectorText = rule.selectorText.replace(":hover", ":active");
                    }
                }
            }
        }
    }
}

您需要从全局ontouchstart事件处理程序中调用一次hoverTouchUnstick()。并且此解决方案将完美地工作。
Jusid

1

将此JS代码添加到您的页面:

document.body.className = 'ontouchstart' in document.documentElement ? '' : 'hover';

现在在您的CSS中,在每次悬停之前添加如下所示的悬停类:

.hover .foo:hover {}

如果设备是触摸设备,则主体类别将为空,否则其类别将悬停并应用规则!


没有为我工作,但是这样做了:document.body.className = 'ontouchstart' in window ? '' : 'hover';
drskullster

1

我可以为每个按钮在ontouchend上添加一个no-hover类,并使CSS像这样:> button:not(.no-hover):hover {background-color:blue; },但这可能会降低性能,并且无法正确处理Chromebook Pixel这样的设备(既有触摸屏又有鼠标)。

这是正确的起点。下一步:在以下事件上应用/删除nohover类(使用jQuery演示)

buttonelement
 .on("touchend touchcancel",function(){$(this).addClass("nohover")})
 .on("touchstart mouseover",function({$(this).removeClass("nohover")});   

注意:如果您希望将其他类应用于buttonelement,则CSS中的:not(.nohover)将无法再按预期工作。而不是您必须添加具有默认值和!important标签的单独定义来覆盖悬停样式:.nohover {background-color:white!important}

这甚至可以正确处理Chromebook Pixel(具有触摸屏和鼠标)之类的设备!而且我不认为这是主要的性能杀手...


1

一个对我有用的解决方案:

html {
   -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

将此代码添加到样式表。

我想摆脱单击链接时iOS Safari上显示的灰色背景。但这似乎还有更多。现在单击按钮(带有:hover伪类!)立即打开!我只在iPad上测试过,不知道它是否可以在其他设备上使用。


1

我想我已经找到了一个解决类似问题的优雅(最小js)解决方案:

使用jQuery,您可以使用以下方法在主体(或任何其他元素)上触发悬停 .mouseover()

因此,我只需将this处理程序附加到元素的ontouchend事件,如下所示:

var unhover = function() {
  $("body").mousover();  
};
.hoverable {
  width: 100px;
  height: 100px;
  background: teal;
  cursor: pointer;
}

.hoverable:hover {
  background: pink;
}
<div class="hoverable" ontouchend={unhover}></div>

但是,这仅在触发了其他一些触摸事件(如滑动或其他触摸)后才从元素中删除:hover伪类。


1
对于您的代码段,在我触摸它后,正方形仍然保持粉红色。我想您真的没有解决此问题中提出的问题吗?
Kevin Lee

此解决方案不起作用。首先,您使用了错误的方法来调用事件,应该使用.trigger()。其次,无论哪种方式都不适用于移动Safari。
xHocquet

1

我有一个很好的解决方案,我想分享。首先,您需要像这样检测用户是否在移动设备上:

var touchDevice = /ipad|iphone|android|windows phone|blackberry/i.test(navigator.userAgent.toLowerCase());

然后只需添加:

if (!touchDevice) {
    $(".navbar-ul").addClass("hoverable");
}

在CSS中:

.navbar-ul.hoverable li a:hover {
    color: #fff;
}

2
在混合设备(例如Windows触摸屏PC)上不起作用。
cspolton

1

我遇到了类似的问题,我的应用程序与所有屏幕尺寸都兼容,而在桌面屏幕尺寸中却产生了很多悬停效果 /鼠标的设备中,后来我意识到基于触摸的设备会导致一种称为粘滞的情况-hover,这对于让基于触摸的设备用户正常运行的应用来说是一个障碍。

我们在应用程序中使用了SCSS。我定义了一个mixin来照顾基于触摸的设备。

@mixin hover-support {
  @media not all and (pointer: coarse) {
    &:hover {
      @content;
    }
  }
}

然后我将所有css类放在下面的代码段下。

   @include hover-support() {
    // Your css-classes or css that you want to apply on those devices that support hover.
   }

例如,我们有一个用于使图标动画化的类,当您将鼠标悬停在图标上时,该类便会触发,如您从CSS中看到的那样,但是在基于触摸的设备中,它受到粘滞悬停效果的影响,然后将其放置在@中包括hover-support(),以确保悬浮仅适用于支持悬浮的设备。

@include hover-support() {
  .animate-icon {
    -webkit-transition: all 0.2s;
    transition: all 0.2s;
    &:hover {
      transform: scale(1.3);
      filter: brightness(85%);
      cursor: pointer;
    }
  }
}

1

这是一些简单的JavaScript代码,不需要开发人员编辑CSS或编写任何新的CSS规则。我使用来为Bootstrap按钮编写了此代码class="btn",但是它可以与具有特定类名的任何按钮一起使用。

这些步骤是:

  1. 确定这是否是触摸设备
  2. 如果是,则遍历其中的每个CSS规则 document.styleSheets
  3. 删除同时包含.btn和的任何规则:hover

消除所有.btn :hoverCSS规则可确保按钮上没有视觉上的悬停效果。

步骤1:侦测触控装置

检查媒体查询是否存在(hover: none)

    const hasMatchMedia = typeof window.matchMedia !== 'undefined';
    /**
     * determine if device is touch-capable
     * true - device is touch-capable
     * false - device is not touch-capable
     * null - unable to determine touch capability
     * @return {null|boolean}
     */
    const hasTouch = () => {
      if (hasMatchMedia) {
        return window.matchMedia('(hover: none)').matches;
      }
      return null;
    };

第2步:删除包含`btn`和`:hover`的CSS规则

    /**
     * remove all CSS rules contaning both '.btn' and ':hover'
     * @return {number} count of rules deleted
     */
    function removeBtnHovers () {

      let rulesDeleted = 0;

      // recursively delete '.btn:hover' rules
      function recursiveDelete (rules, styleSheet) {

        if (typeof rules === 'undefined' ||
          typeof rules.length === 'undefined' ||
          rules.length <= 0) {
          return;
        }

        // iterate in reverse order,
        // deleting any rule containing both '.btn' and ':hover'
        const ruleLen = rules.length;
        for (let i = ruleLen - 1; i >= 0; i--) {
          const rule = rules[i];
          if (typeof rule.cssRules === 'undefined') {
            // a standard rule, evaluate it
            const cssText = rule.cssText;
            if (typeof cssText === 'string' &&
              cssText.includes('.btn') &&
              cssText.includes(':hover')) {
              styleSheet.deleteRule(i);
              rulesDeleted++;
            }
          } else {
            // rule contains cssRules, iterate over them
            recursiveDelete(rule.cssRules, rule);
          }
        }
      }

      // iterate over all style sheets in document
      for (const styleSheet of document.styleSheets) {
        let rules = styleSheet.cssRules;
        if (!rules) { continue; }
        recursiveDelete(rules, styleSheet);
      }
      return rulesDeleted;
    }

完整的代码在GitHubnpm上

terrymorse.com上进行现场演示。


这是否还会消除具有鼠标/触控板的触摸屏设备的悬停效果?
延森

@Jensei可能。如果设备与匹配@media (hover:none),或者当用户首次触摸屏幕时,将删除悬停规则。您可以在现场演示页面上尝试一下以确保。
terrymorse

0

您可以在:active状态上设置背景颜色,并提供:focus 默认的背景。

如果您通过设置背景颜色onfocus/ontouch,一旦:focus状态消失,颜色样式将保持不变。当失去焦点时,还
需要重新设置onblur以恢复默认bg。


但是我想保持鼠标用户的悬停效果。
克里斯(Chris

:hover和:active可以接收相同的CSS,在:focus上您有问题。实际上,如果您通过onfocus设置背景颜色,则一旦焦点消失,颜色样式将保持不变。您还需要重置onlur才能恢复默认bg
G-Cyrillus 2013年

0

这对我有用:将悬停样式添加到新类中

.fakehover {background: red}

然后根据需要添加/删除类

$(".someclass > li").on("mouseenter", function(e) {
  $(this).addClass("fakehover");
});
$(".someclass > li").on("mouseleave", function(e) {
  $(this).removeClass("fakehover");
});

重复触摸开始和触摸结束事件。或任何您想要获得期望结果的事件,例如,我希望在触摸屏上切换悬停效果。


0

根据Darren Cooks的回答,如果您将手指移到另一个元素上,该回答也将起作用。

请参阅在touchend事件期间“查找元素手指是否已打开”

jQuery(function() {
    FastClick.attach(document.body);
});
// Prevent sticky hover effects for buttons on touch devices
// From https://stackoverflow.com/a/17234319
//
//
// Usage:
// <a href="..." touch-focus-fix>..</a>
//
// Refactored from a directive for better performance and compability
jQuery(document.documentElement).on('touchend', function(event) {
  'use strict';

  function fix(sourceElement) {
    var el = $(sourceElement).closest('[touch-focus-fix]')[0];
    if (!el) {
      return;
    }
    var par = el.parentNode;
    var next = el.nextSibling;
    par.removeChild(el);
    par.insertBefore(el, next);
  }

  fix(event.target);
  var changedTouch = event.originalEvent.changedTouches[0];
  // http://www.w3.org/TR/2011/WD-touch-events-20110505/#the-touchend-event
  if (!changedTouch) {
    return;
  }
  var touchTarget = document.elementFromPoint(changedTouch.clientX, changedTouch.clientY);
  if (touchTarget && touchTarget !== event.target) {
    fix(touchTarget);
  }
});

Codepen Demo


0

您可以尝试这种方式。

javascript:

var isEventSupported = function (eventName, elementName) {
    var el = elementName ? document.createElement(elementName) : window;
    eventName = 'on' + eventName;
    var isSupported = (eventName in el);
    if (!isSupported && el.setAttribute) {
        el.setAttribute(eventName, 'return;');
        isSupported = typeof el[eventName] == 'function';
    }
    el = null;
    return isSupported;
};

if (!isEventSupported('touchstart')) {
    $('a').addClass('with-hover');
}

CSS:

a.with-hover:hover {
  color: #fafafa;
}

0

到目前为止,我在项目中所做的就是还原:hover触摸设备上的更改:

.myhoveredclass {
    background-color:green;
}
.myhoveredclass:hover {
    background-color:red;
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
    .myhoveredclass:hover, .myhoveredclass:active, .myhoveredclass:focus {
        background-color:green;
    }
}

所有类别名称和命名颜色仅用于演示目的;-)


0

分两步完美运行。

  1. 将您的身体标签设置为这样<body ontouchstart="">。我不喜欢这种“ hack”,但是它允许iOS上的Safari立即响应触摸。不知道如何,但是它有效。

  2. 像这样设置您的可触摸类:

    // I did this in SASS, but this should work with normal CSS as well
    
    // Touchable class
    .example {
    
        // Default styles
        background: green;
    
        // Default hover styles 
        // (Think of this as Desktop and larger)
        &:hover {
            background: yellow;
        }
    
        // Default active styles
        &:active {
            background: red;
        }
    
        // Setup breakpoint for smaller device widths
        @media only screen and (max-width: 1048px) {
    
            // Important!
            // Reset touchable hover styles
            // You may want to use the same exact styles as the Default styles
            &:hover {
                background: green;
            }
    
            // Important!
            // Touchable active styles
            &:active {
                background: red;
            }
        }
    }

您可能还希望删除可触摸类上的所有动画。Android Chrome似乎比iOS慢一些。

如果用户在触摸您的班级时滚动页面,这还将导致处于活动状态。


0

当浏览器尝试操纵屏幕时,:hover :focus :active可能会丢失某些移动设备上的粘滞或卡住的问题<meta name="viewport" content="width=device-width">


0

对我来说,解决方案是在touchend之后克隆并替换节点...我讨厌这样做,但即使尝试使用offsetHeight重新绘制元素也无法正常工作

    let cloneNode = originNode.cloneNode( true );
    originNode.parentNode.replaceChild( cloneNode, originNode );

最后,这对我不起作用...我的情况是,我必须克隆整个扩展的ES6和几个事件侦听器,并且它开始变得复杂起来以解决这么小的问题。
禁止

0

可以通过交换HTML类来完成。它应该比删除整个元素更不容易出现毛刺,尤其是对于较大的图像链接等。

我们还可以决定是否要悬停在通过触摸滚动(触摸移动)时触发状态,甚至添加超时来延迟它们。

我们代码中唯一的重大变化将是使用其他HTML类,例如<a class='hover'></a>实现新行为的元素。

的HTML

<a class='my-link hover' href='#'>
    Test
</a>

的CSS

.my-link:active, // :active can be turned off to disable hover state on 'touchmove'
.my-link.hover:hover {

    border: 2px dotted grey;
}

JS(使用jQuery)

$('.hover').bind('touchstart', function () {

   var $el;
   $el = $(this);
   $el.removeClass('hover'); 

   $el.hover(null, function () {
      $el.addClass('hover');
   });
});

https://codepen.io/mattrcouk/pen/VweajZv

--

不过,我没有任何可以同时使用鼠标和触摸屏进行测试的设备。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.