CSS :active 伪类在移动 safari 中不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3885018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
:active pseudo-class doesn't work in mobile safari
提问by Jesse Rusak
In Webkit on iPhone/iPad/iPod, specifying styling for an :active pseudo-class for an <a>
tag doesn't trigger when you tap on the element. How can I get this to trigger? Example code:
在 iPhone/iPad/iPod 上的 Webkit 中,为<a>
标签指定 :active 伪类的样式不会在您点击元素时触发。我怎样才能触发这个?示例代码:
<style>
a:active {
background-color: red;
}
</style>
<!-- snip -->
<a href="#">Click me</a>
回答by wilsonpage
<body ontouchstart="">
...
</body>
Applied just once, as opposed to every button element seemed to fix all buttons on the page. Alternatively you could use this small JS library called 'Fastclick'. It speed up click events on touch devices and takes care of this issue too.
只应用一次,而不是每个按钮元素似乎都修复了页面上的所有按钮。或者,您可以使用这个名为“ Fastclick”的小型 JS 库。它加快了触摸设备上的点击事件,并解决了这个问题。
回答by user128216
As other answers have stated, iOS Safari doesn't trigger the :active
pseudo-class unless a touch event is attached to the element, but so far this behaviour has been "magical". I came across this little blurb on the Safari Developer Librarythat explains it (emphasis mine):
正如其他答案所述,:active
除非将触摸事件附加到元素,否则iOS Safari 不会触发伪类,但到目前为止,这种行为一直是“神奇的”。我在Safari 开发者库上看到了这个解释它的小简介(重点是我的):
You can also use the
-webkit-tap-highlight-color
CSS property in combination with setting a touch event to configure buttons to behave similar to the desktop. On iOS, mouse events are sent so quickly that the down or active state is never received.Therefore, the:active
pseudo state is triggered only when there is a touch event set on the HTML element—for example, when ontouchstart is set on the element as follows:<button class="action" ontouchstart="" style="-webkit-tap-highlight-color: rgba(0,0,0,0);"> Testing Touch on iOS </button>
Now when the button is tapped and held on iOS, the button changes to the specified color without the surrounding transparent gray color appearing.
您还可以将
-webkit-tap-highlight-color
CSS 属性与设置触摸事件结合使用,以将按钮配置为与桌面类似。在 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 上点击并按住按钮时,按钮会更改为指定的颜色,而不会出现周围的透明灰色。
In other words, setting an ontouchstart
event (even if it's empty) is explicitly telling the browser to react to touch events.
换句话说,设置一个ontouchstart
事件(即使它是空的)是明确告诉浏览器对触摸事件做出反应。
In my opinion, this is flawed behaviour, and probably dates back to the time when the "mobile" web was basically nonexistent (take a look at those screenshots on the linked page to see what I mean), and everything was mouse oriented. It is interesting to note that other, newer mobile browsers, such as on Android, display `:active' pseudo-state on touch just fine, without any hacks like what is needed for iOS.
在我看来,这是有缺陷的行为,可能可以追溯到“移动”网络基本上不存在的时代(看看链接页面上的那些屏幕截图,看看我的意思),一切都是面向鼠标的。有趣的是,其他较新的移动浏览器,例如在 Android 上,在触摸时显示 `:active' 伪状态就好了,没有像 iOS 需要的任何黑客。
(Side-note: If you want to use your own custom styles on iOS, you can also disable the default grey translucent box that iOS uses in place of the :active
pseudo-state by using the -webkit-tap-highlight-color
CSS property, as explained in the same linked page above.)
(旁注:如果您想在 iOS 上使用您自己的自定义样式,您还可以:active
通过使用-webkit-tap-highlight-color
CSS 属性禁用 iOS 使用的默认灰色半透明框代替伪状态,如上述相同链接页面所述.)
After some experimentation, the expected solution of setting an ontouchstart
event on the <body>
element that alltouch events then bubble to does not work fully. If the element is visible in the viewport when the page loads, then it works fine, but scrolling down and tapping an element that was out of the viewport does nottrigger the :active
pseudo-state like it should. So, instead of
经过一些实验,在元素ontouchstart
上设置一个事件<body>
,所有触摸事件然后冒泡到的预期解决方案并不完全有效。如果元素中视可见的页面加载时,那么它工作正常,但向下滚动和攻丝,这是视口拖出元素并没有引发:active
像它应该伪状态。所以,而不是
<!DOCTYPE html>
<html><body ontouchstart></body></html>
attach the event to all elements instead of relying on the event bubbling up to the body (using jQuery):
将事件附加到所有元素,而不是依赖于事件冒泡到正文(使用 jQuery):
$('body *').on('touchstart', function (){});
However, I am not aware of the performance implications of this, so beware.
但是,我不知道这对性能的影响,所以要小心。
EDIT:There is one serious flaw with this solution: even touching an element while scrolling the page will activate the :active
pseudo state. The sensitivity is too strong. Android solves this by introducing a very small delay before the state is shown, which is cancelled if the page is scrolled. In light of this, I suggest using this only on select elements. In my case, I am developing a web-app for use out in the field which is basically a list of buttons to navigate pages and submit actions. Because the whole page is pretty much buttons in some cases, this won't work for me. You can, however, set the :hover
pseudo-state to fill in for this instead. After disabling the default grey box, this works perfectly.
编辑:此解决方案存在一个严重缺陷:即使在滚动页面时触摸元素也会激活:active
伪状态。灵敏度太强了。Android 通过在显示状态之前引入一个非常小的延迟来解决这个问题,如果滚动页面,延迟就会被取消。鉴于此,我建议仅在选择元素上使用它。就我而言,我正在开发一个用于该领域的网络应用程序,它基本上是一个用于导航页面和提交操作的按钮列表。因为在某些情况下整个页面几乎都是按钮,所以这对我不起作用。但是,您可以设置:hover
伪状态来填充它。禁用默认的灰色框后,这完美地工作。
回答by Jesse Rusak
Add an event handler for ontouchstart in your <a> tag. This causes the CSS to magically work.
在 <a> 标签中为 ontouchstart 添加一个事件处理程序。这会导致 CSS 神奇地工作。
<a ontouchstart="">Click me</a>
回答by dhqvinh
Thisworks for me:
这对我有用:
document.addEventListener("touchstart", function() {},false);
Note: if you do this trick it is also worth removing the default tap–highlight colour Mobile Safari applies using the following CSS rule.
注意:如果您使用此技巧,还值得使用以下 CSS 规则移除 Mobile Safari 应用的默认点击高亮颜色。
html {
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
回答by Ali
As of Dec 8, 2016, the accepted answer (<body ontouchstart="">...</body>
) does not work for me on Safari 10 (iPhone 5s): That hack only works for those elements that were visible on page load.
截至 2016 年 12 月 8 日,已接受的答案 ( <body ontouchstart="">...</body>
) 在 Safari 10 (iPhone 5s) 上对我不起作用:该 hack 仅适用于在页面加载时可见的那些元素。
However, adding:
但是,添加:
<script type='application/javascript'>
document.addEventListener("touchstart", function() {}, false);
</script>
to the head
does work the way I want, with the downside that now all touch events during scrolling also trigger the :active
pseudo-state on the touched elements. (If this is a problem for you, you might consider FighterJet's:hover
workaround.)
在head
不工作的方式我想,与缺点,现在还滚动在所有触摸事件触发:active
的感动元素伪状态。(如果这对您来说是个问题,您可以考虑使用FighterJet 的:hover
解决方法。)
回答by Redeye
//hover for ios
-webkit-tap-highlight-color: #ccc;
This works for me, add to your CSS on the element that you want to highlight
这对我有用,将要突出显示的元素添加到 CSS 中
回答by tahdhaze09
Are you using all of the pseudo-classes or just the one? If you're using at least two, make sure they're in the right order or they all break:
你是使用所有的伪类还是只使用一个?如果您至少使用两个,请确保它们的顺序正确,否则它们都会损坏:
a:link
a:visited
a:hover
a:active
..in that order. Also, If you're just using :active, add a:link, even if you're not styling it.
..以该顺序。另外,如果您只是使用 :active,请添加一个:link,即使您没有对其进行样式设置。
回答by dmitrizzle
I've published a tool that should solve this issue for you.
我已经发布了一个工具,应该可以为您解决这个问题。
On the surface the problem looks simple, but in reality the touch & click behaviour needs to be customized quite extensively, including timeout functions and things like "what happens when you scroll a list of links" or "what happens when you press link and then move mouse/finger away from active area"
从表面上看,问题看起来很简单,但实际上触摸和点击行为需要非常广泛地定制,包括超时功能和诸如“滚动链接列表时会发生什么”或“按下链接时会发生什么,然后将鼠标/手指从活动区域移开”
This should solve it all at once: https://www.npmjs.com/package/active-touch
这应该一次解决所有问题:https: //www.npmjs.com/package/active-touch
You'll need to either have your :active styles assigned to .active class or choose your own class name. By default the script will work with all link elements, but you can overwrite it with your own array of selectors.
您需要将您的 :active 样式分配给 .active 类或选择您自己的类名。默认情况下,脚本将处理所有链接元素,但您可以使用自己的选择器数组覆盖它。
Honest, helpful feedback and contributions much appreciated!
非常感谢诚实、有用的反馈和贡献!
回答by Noob Dev
For those who don't want to use the ontouchstart, you can use this code
对于那些不想使用 ontouchstart 的人,您可以使用此代码
<script>
document.addEventListener("touchstart", function(){}, true);
</script>
回答by daffinm
I tried this answerand its variants, but none seemed to work reliably (and I dislike relying on 'magic' for stuff like this). So I did the following instead, which works perfectly on all platforms, not just Apple:
我尝试了这个答案及其变体,但似乎没有一个可靠地工作(而且我不喜欢依靠“魔法”来做这样的事情)。所以我做了以下操作,它在所有平台上都可以完美运行,而不仅仅是 Apple:
- Renamed css declarations that used
:active
to.active
. Made a list of all the affected elements and added
pointerdown/mousedown/touchstart
event handlers to apply the.active
class andpointerup/mouseup/touchend
event handlers to remove it. Using 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'); });
- 更名为CSS声明所使用
:active
到.active
。 列出所有受影响的元素并添加
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'); });
This was a bit tedious, but now I have a solution that is less vulnerable to breakage between Apple OS versions. (And who needs something like this breaking?)
这有点乏味,但现在我有了一个解决方案,在 Apple OS 版本之间不易损坏。(谁需要这样的破坏?)