正如其他答案所述,iOS Safari 不会触发 :active 伪类,除非将触摸事件附加到元素,但到目前为止,这种行为是“神奇的”。我在Safari Developer Library 上看到了这个解释它的小简介(强调我的):
您还可以将-webkit-tap-highlight-color CSS 属性与设置触摸事件结合使用,以配置按钮的行为类似于桌面。 在 iOS 上,鼠标事件发送得非常快,以至于永远不会收到按下或活动状态。因此,: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 上使用自己的自定义样式,您还可以使用 -webkit-tap-highlight-color CSS 属性禁用 iOS 使用的默认灰色半透明框来代替 :active 伪状态,如上面同一链接页面中所述。)
经过一些实验,在 all 触摸事件然后冒泡的 <body> 元素上设置 ontouchstart 事件的预期解决方案不能完全工作。如果页面加载时元素在视口中可见,那么它可以正常工作,但是向下滚动并点击视口外的元素不会不触发:active类似的伪状态应该。所以,而不是
<!DOCTYPE html>
<html><body ontouchstart></body></html>
将事件附加到所有元素,而不是依赖事件冒泡到正文(使用 jQuery):
$('body *').on('touchstart', function (){});
但是,我不知道这对性能的影响,所以要小心。
编辑:此解决方案存在一个严重缺陷:即使在滚动页面时触摸元素也会激活:active 伪状态。灵敏度太强了。 Android 通过在显示状态之前引入一个非常小的延迟来解决这个问题,如果页面滚动则会取消该延迟。鉴于此,我建议仅在选择元素上使用它。就我而言,我正在开发一个用于该领域的网络应用程序,它基本上是一个用于导航页面和提交操作的按钮列表。因为在某些情况下整个页面几乎都是按钮,所以这对我不起作用。但是,您可以设置 :hover 伪状态来代替它。禁用默认的灰色框后,效果很好。