:active 伪类在 mobile safari 中不起作用

发布于 2024-09-26 21:23:08 字数 300 浏览 0 评论 0原文

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

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

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:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

情话难免假 2024-10-03 21:23:08
<body ontouchstart="">
    ...
</body>

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

<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.

恏ㄋ傷疤忘ㄋ疼 2024-10-03 21:23:08

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

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

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

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

在我看来,这是有缺陷的行为,并且可能可以追溯到“移动”网络基本上不存在的时候(看看链接页面上的那些屏幕截图,看看我的意思),并且一切都是面向鼠标的。有趣的是,其他较新的移动浏览器,例如 Android 上的浏览​​器,在触摸时可以很好地显示“:active”伪状态,而无需像 iOS 那样进行任何修改。

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


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

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

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

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

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


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

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 Library that explains it (emphasis mine):

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.

In other words, setting an ontouchstart event (even if it's empty) is explicitly telling the browser to react to touch events.

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.

(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.)


After some experimentation, the expected solution of setting an ontouchstart event on the <body> element that all touch 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 not trigger the :active pseudo-state like it should. So, instead of

<!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):

$('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.

这个俗人 2024-10-03 21:23:08

Add an event handler for ontouchstart in your <a> tag. This causes the CSS to magically work.

<a ontouchstart="">Click me</a>
微暖i 2024-10-03 21:23:08

截至 2016 年 12 月 8 日,接受的答案 (...) 在 Safari 10 (iPhone 5s) 上不适用于我: hack 仅适用于页面加载时可见的那些元素。

但是,添加:

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

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

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.

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.)

阳光下的泡沫是彩色的 2024-10-03 21:23:08

有效对我来说:

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

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

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

This works 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.

html {
    -webkit-tap-highlight-color: rgba(0,0,0,0);
}
辞别 2024-10-03 21:23:08
//hover for ios
-webkit-tap-highlight-color: #ccc;

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

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

This works for me, add to your CSS on the element that you want to highlight

清醇 2024-10-03 21:23:08

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

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

..按该顺序。另外,如果您只是使用 :active,请添加一个:link,即使您没有设计它的样式。

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.

风和你 2024-10-03 21:23:08

对于那些不想使用ontouchstart的人,可以使用这段代码

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

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

<script>
 document.addEventListener("touchstart", function(){}, true);
</script>
太阳公公是暖光 2024-10-03 21:23:08

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

表面上看,这个问题看起来很简单,但实际上,触摸和触摸是一个很大的问题。单击行为需要进行广泛的自定义,包括超时功能以及诸如“滚动链接列表时会发生什么”或“按下链接然后将鼠标/手指移离活动区域时会发生什么”之类的事情,

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

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

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

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

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.

Honest, helpful feedback and contributions much appreciated!

不羁少年 2024-10-03 21:23:08

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

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

    让 controlActivationEvents = window.PointerEvent ? “pointerdown”:“touchstart mousedown”;
    让 controlDeactivationEvents = window.PointerEvent ? "pointerup pointleave" : "touchend mouseup mouseleave";
    
    let clickableThings = '<逗号分隔的选择器列表>';
    $(clickableThings).on(controlActivationEvents,函数 (e) {
        $(this).addClass('active');
    }).on(controlDeactivationEvents, 函数 (e) {
        $(this).removeClass('active');
    });
    

这有点乏味,但现在我有了一个更不容易在 Apple 操作系统版本之间出现损坏的解决方案。 (谁需要这样的破坏?)

I tried this answer and 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:

  1. Renamed css declarations that used :active to .active.
  2. Made a list of all the affected elements and added pointerdown/mousedown/touchstart event handlers to apply the .active class and pointerup/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');
    });
    

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?)

知足的幸福 2024-10-03 21:23:08

解决方案是依赖 :target 而不是 :active

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

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

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

A solution is to rely on :target instead of :active:

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

The style will be triggered when the anchor is targeted by the current url, which is robust even on mobile. The drawback is you need an other link to clear the anchor in the url. Complete example:

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

靖瑶 2024-10-03 21:23:08

与这个问题没有100%相关,
但你也可以使用 css 兄弟 hack 来实现这一点

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;
    }
  }

No 100% related to this question,
but you can use css sibling hack to achieve this as well

HTML

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

SCSS

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

If you would like to use pure html/css tooltip

span {
  display: none;
}
input {
    &:checked ~ span {
      display: block;
    }
  }
痴梦一场 2024-10-03 21:23:08
<!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>
<!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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文