115

<a>在 iPhone/iPad/iPod 上的 Webkit 中,当您点击元素时,不会触发为标签指定 :active 伪类的样式。我怎样才能让它触发?示例代码:

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

13 回答 13

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

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

于 2012-01-16T09:26:15.257 回答
64

正如其他答案所述,iOS Safari 不会触发:active伪类,除非将触摸事件附加到元素,但到目前为止,这种行为是“神奇的”。我在Safari 开发者库中看到了这个解释它的小简介(强调我的):

您还可以将-webkit-tap-highlight-colorCSS 属性与设置触摸事件结合使用,以将按钮配置为类似于桌面的行为。在 iOS 上,鼠标事件的发送速度非常快,以至于永远不会收到 down 或 active 状态。因此,:active只有在 HTML 元素上设置了触摸事件时才会触发伪状态——例如,在元素上设置了 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 所需的任何 hack。

(旁注:如果您想在 iOS 上使用自己的自定义样式,您还可以:active使用 CSS 属性禁用 iOS 使用的默认灰色半透明框来代替伪状态-webkit-tap-highlight-color,如上面同一链接页面中所述.)


经过一些实验,在所有触摸事件随后冒泡的元素上设置ontouchstart事件的预期解决方案不能完全工作。如果页面加载时元素在视口中可见,则它可以正常工作,但向下滚动并点击视口外的元素不会触发应有的伪状态。所以,而不是<body>:active

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

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

$('body *').on('touchstart', function (){});

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


编辑:此解决方案存在一个严重缺陷:即使在滚动页面时触摸元素也会激活:active伪状态。灵敏度太强了。Android 通过在显示状态之前引入一个非常小的延迟来解决这个问题,如果页面滚动则会取消该延迟。鉴于此,我建议仅在选择元素上使用它。就我而言,我正在开发一个用于该领域的网络应用程序,它基本上是一个用于导航页面和提交操作的按钮列表。因为在某些情况下整个页面几乎都是按钮,所以这对我不起作用。但是,您可以设置:hover伪状态来代替它。禁用默认的灰色框后,它可以完美运行。

于 2015-11-12T21:14:43.973 回答
40

在 <a> 标记中添加 ontouchstart 的事件处理程序。这会导致 CSS 神奇地工作。

<a ontouchstart="">Click me</a>
于 2010-10-07T19:10:23.373 回答
7

对我有用:

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

注意:如果您使用此技巧,还值得使用以下 CSS 规则删除移动 Safari 应用的默认点击高亮颜色。

html {
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}
于 2016-12-19T06:52:27.167 回答
6

截至 2016 年 12 月 8 日,已接受的答案<body ontouchstart="">...</body>

但是,添加:

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

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

于 2016-12-08T17:13:14.853 回答
4
//hover for ios
-webkit-tap-highlight-color: #ccc;

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

于 2015-05-18T10:54:51.023 回答
3

你是使用所有的伪类还是只使用一个?如果您至少使用两个,请确保它们的顺序正确,否则它们都会中断:

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

..以该顺序。此外,如果您只是使用 :active,请添加:链接,即使您没有对其进行样式设置。

于 2010-10-07T19:15:11.333 回答
2

不想使用 ontouchstart 的可以使用这段代码

<script>
 document.addEventListener("touchstart", function(){}, true);
</script>
于 2019-04-16T23:13:45.123 回答
1

我已经发布了一个可以为你解决这个问题的工具。

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

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

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

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

于 2017-03-19T04:49:47.070 回答
1

我尝试了这个答案及其变体,但似乎没有一个能可靠地工作(而且我不喜欢依靠“魔法”来处理这样的事情)。所以我做了以下操作,它在所有平台上都能完美运行,而不仅仅是 Apple:

  1. :active重命名了过去的css 声明.active
  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 版本之间的破坏。(谁需要这样的破坏?)

于 2019-10-12T20:52:35.143 回答
0

一个解决方案是依靠:target而不是:active

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

当锚点被当前 url 定位时,样式将被触发,即使在移动设备上也是健壮的。缺点是您需要另一个链接来清除 url 中的锚点。完整示例:

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

于 2018-03-03T13:36:04.653 回答
-3

没有 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;
    }
  }
于 2016-10-28T05:18:20.573 回答
-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>
于 2012-11-27T16:08:47.107 回答