:active pseudo-class在移动safari中不起作用

时间:2010-10-07 19:09:32

标签: iphone css webkit mobile-safari pseudo-class

在iPhone / iPad / iPod上的Webkit中,当您点击元素时,不会触发为<a>标记指定样式的活动伪类。我该如何触发?示例代码:

<style> 
a:active { 
    background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>

13 个答案:

答案 0 :(得分:218)

<body ontouchstart="">
    ...
</body>

只应用一次,而不是每个按钮元素似乎都修复了页面上的所有按钮。或者,您可以使用名为“Fastclick”的小型JS库。它可以加快触摸设备上的点击事件并处理这个问题。

答案 1 :(得分:44)

正如其他答案所述,iOS Safari不会触发:active伪类,除非触摸事件附加到元素,但到目前为止这种行为一直是“神奇的”。我在Safari Developer Library上发现了这个小小的模糊点(强调我的):

  

您还可以将-webkit-tap-highlight-color CSS属性与设置触摸事件结合使用,以将按钮配置为与桌面类似。 在iOS上,鼠标事件的发送速度非常快,以至于永远不会收到关闭或活动状态。因此,只有在HTML元素上设置了触摸事件时才会触发:active伪状态 - 例如,在元素上设置ontouchstart时如下:

<button class="action" ontouchstart=""
        style="-webkit-tap-highlight-color: rgba(0,0,0,0);">
    Testing Touch on iOS
</button>
     

现在,当点击并按住iOS按钮时,按钮会变为指定的颜色,而不会出现周围的透明灰色。

换句话说,设置ontouchstart事件(即使它为空)明确告诉浏览器对触摸事件作出反应。

在我看来,这是一个有缺陷的行为,可能追溯到“移动”网络基本上不存在的时候(看看链接页面上的那些截图,看看我的意思),一切都是鼠标导向。值得注意的是,其他更新的移动浏览器,例如在Android上,在触摸时显示`:active'伪状态就好了,没有像iOS所需的任何黑客。

(旁注:如果您想在iOS上使用自己的自定义样式,您还可以使用{{1}禁用iOS使用的默认灰色半透明框来代替:active伪状态CSS属性,如上面相同的链接页面所述。)

经过一些实验后,在-webkit-tap-highlight-color元素上设置ontouchstart事件的预期解决方案 all 触摸事件然后冒泡到达不起作用。如果元素在页面加载时在视口中可见,那么它工作正常,但向下滚动并点击视口外的元素会触发<body>伪状态喜欢它。所以,而不是

:active

将事件附加到所有元素,而不是依赖于冒泡到身体的事件(使用jQuery):

<!DOCTYPE html>
<html><body ontouchstart></body></html>

但是,我不知道这对性能的影响,所以要小心。

编辑:此解决方案存在一个严重缺陷:在滚动页面时触摸元素会激活$('body *').on('touchstart', function (){}); 伪状态。灵敏度太强了。 Android通过在显示状态之前引入非常小的延迟来解决此问题,如果页面滚动则取消该延迟。鉴于此,我建议仅在选择元素上使用它。就我而言,我正在开发一个在该领域使用的网络应用程序,它基本上是一个用于浏览页面和提交动作的按钮列表。因为在某些情况下整个页面几乎都是按钮,这对我来说不起作用。但是,您可以设置:active伪状态来填充此内容。禁用默认灰色框后,这非常有效。

答案 2 :(得分:39)

在&lt; a&gt;中为ontouchstart添加事件处理程序标签。这会导致CSS神奇地工作。

<a ontouchstart="">Click me</a>

答案 3 :(得分:7)

This适合我:

document.addEventListener("touchstart", function() {},false);

注意:如果您执行此操作,还可以使用以下CSS规则删除Mobile Safari应用的默认点击突出显示颜色。

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

答案 4 :(得分:4)

截至2016年12月8日,接受的答案(<body ontouchstart="">...</body>)在Safari 10(iPhone 5s)上对我不起作用:该hack仅适用于在页面加载时可见的元素。

但是,添加:

<script type='application/javascript'>
  document.addEventListener("touchstart", function() {}, false);
</script>

head确实按照我想要的方式工作,但缺点是现在滚动期间的所有触摸事件也会触发触摸元素上的:active伪状态。 (如果这对您来说是个问题,您可以考虑使用FighterJet's :hover解决方法。)

答案 5 :(得分:3)

您使用的是所有伪类还是仅使用伪类?如果您使用至少两个,请确保它们的顺序正确或者它们都已破坏:

a:link
a:visited
a:hover
a:active

..按此顺序。此外,如果您只是使用:active,请添加:link,即使您没有设置样式。

答案 6 :(得分:3)

//hover for ios
-webkit-tap-highlight-color: #ccc;

这适用于我,在要突出显示的元素上添加到CSS

答案 7 :(得分:1)

我发布了一个可以为您解决此问题的工具。

表面上问题看起来很简单,但实际上触摸和点击行为需要进行相当广泛的定制,包括超时功能和诸如“当您滚动链接列表时会发生什么”或“当您按下链接然后将鼠标/手指从活动区域移开时会发生什么”

这应该立即解决所有问题:https://www.npmjs.com/package/active-touch

您需要将您的:活动样式分配给.active类或选择您自己的类名。默认情况下,脚本将使用所有链接元素,但您可以使用自己的选择器数组覆盖它。

诚实,有用的反馈和贡献非常感谢!

答案 8 :(得分:0)

解决方案是依靠:target代替:active

<style> 
a:target { 
    background-color: red;
}
</style>
<!-- snip -->
<a id="click-me" href="#click-me">Click me</a>

当锚点被当前网址定位时,将触发该样式,即使在移动设备上也是如此。缺点是你需要一个其他链接来清除网址中的锚点。完整的例子:

&#13;
&#13;
a:target { 
    background-color: red;
}
&#13;
<a id="click-me" href="#click-me">Click me</a>
<a id="clear" href="#">Clear</a>
&#13;
&#13;
&#13;

答案 9 :(得分:0)

For those who don't want to use the ontouchstart, you can use this code

<script>
 document.addEventListener("touchstart", function(){}, true);
</script>

答案 10 :(得分:0)

我尝试了this answer及其变体,但似乎没有一个能可靠地工作(而且我不喜欢依靠“魔术”来完成此类工作)。因此,我改为执行以下操作,该操作在所有平台上都可以完美运行,而不仅仅是Apple:

  1. 将使用:active.active的css声明重命名。
  2. 列出所有受影响的元素,并添加pointerdown/mousedown/touchstart事件处理程序以应用.active类和pointerup/mouseup/touchend事件处理程序以将其删除。使用jQuery:

    let controlActivationEvents = window.PointerEvent ? "pointerdown" : "touchstart mousedown";
    let controlDeactivationEvents = window.PointerEvent ? "pointerup pointerleave" : "touchend mouseup mouseleave";
    
    let clickableThings = '<comma separated list of selectors>';
    $(clickableThings).on(controlActivationEvents,function (e) {
        $(this).addClass('active');
    }).on(controlDeactivationEvents, function (e) {
        $(this).removeClass('active');
    });
    

这有点乏味,但是现在我有了一个解决方案,该解决方案不容易受到Apple OS版本之间的损坏的影响。 (谁需要这样的突破?)

答案 11 :(得分:-2)

没有100%与此问题相关, 但你也可以使用css兄弟黑客来实现这个目标

HTML

<input tabindex="0" type="checkbox" id="145"/>
<label for="145"> info</label>
<span> sea</span>

SCSS

input {
    &:checked + label {
      background-color: red;
    }
  }

如果您想使用纯html / css工具提示

span {
  display: none;
}
input {
    &:checked ~ span {
      display: block;
    }
  }

答案 12 :(得分:-6)

<!DOCTYPE html>

<html lang="en">

<head>
<meta charset="utf-8">

<title></title>

<style>
        a{color: red;}
        a:hover{color: blue;}
</style>
</head>

<body>

        <div class="main" role="main">
                <a href="#">Hover</a>
        </div>

</body>
</html>