You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome Mobile中CSS :active状态的JS事件监听及延迟问题

解决Chrome Mobile中:active状态与触摸/点击事件不同步的问题

主问题:如何为:active状态变化添加JavaScript监听器?

没有直接监听CSS :active伪类状态变化的JavaScript API。你可以通过绑定用户交互事件来精准控制高亮逻辑——用自定义CSS类代替:active,在触摸/按下事件触发时添加类,在松开/取消事件触发时移除类,完全绕过原生:active的延迟问题。

额外问题解答

1. 能否消除touchstart与:active之间的约130ms延迟?

可以,有几种有效方案:

  • 给页面元素添加touch-action: manipulation CSS属性,告知浏览器无需处理双击缩放,直接响应触摸事件;
  • 确保已正确设置viewport元标签(你代码中已经添加了<meta name="viewport" content="width=device-width,initial-scale=1"/>,这是基础前提);
  • 放弃原生:active,用前面说的自定义类+事件绑定的方式实现高亮,完全规避伪类的延迟。

2. 为何Chrome 108中仍存在该问题?

虽然2015年后主流浏览器逐步移除了300ms双击缩放延迟,但原生:active在触摸场景下的触发逻辑和触摸事件不同步是另一个问题:浏览器为了区分用户是点击还是滑动操作,会调整:active的触发时机,导致视觉反馈和触摸动作出现延迟。此外,如果页面未明确禁用双击缩放,浏览器可能保留部分延迟逻辑。

3. 触摸延迟不是2015年就解决了吗?

是的,传统的300ms双击缩放延迟在正确配置viewport的情况下已经被移除,但你遇到的:active延迟属于浏览器处理伪类状态与触摸事件序列的逻辑差异,并非传统的缩放延迟,所以会存在不同步的情况。

修改后的代码示例

用自定义类模拟高亮,精准同步触摸/点击动作:

<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<style>
html, body, pre {
  position:absolute; top:0; left:0; right:0; bottom:0;
  margin: 0; user-select: none;
  touch-action: manipulation; /* 禁用双击缩放,加速事件响应 */
}
pre {margin: 10px; overflow-y:auto}
/* 自定义高亮类,替代:active */
pre.highlight {
  background-color:#fee;
}
</style>
</head>
<body>
<pre id="ELEM"></pre>

<script>
const ELEM = document.getElementById("ELEM")
ELEM.appendChild(document.createTextNode(""));

function Print(s) {
  let t = (new Date() / 1000 % 60).toFixed(2).padStart(5,0);
  ELEM.firstChild.nodeValue += `${t}: ${s}\n`;
  ELEM.scrollTop = ELEM.scrollHeight;
}

Print("Hello, world!");

// 控制高亮的函数
function addHighlight() {
  ELEM.classList.add('highlight');
  Print('触发高亮');
}

function removeHighlight() {
  ELEM.classList.remove('highlight');
  Print('移除高亮');
}

// 绑定触摸事件
ELEM.addEventListener('touchstart', addHighlight, {passive: true});
ELEM.addEventListener('touchend', removeHighlight);
ELEM.addEventListener('touchcancel', removeHighlight);

// 绑定鼠标事件
ELEM.addEventListener('mousedown', addHighlight);
ELEM.addEventListener('mouseup', removeHighlight);
ELEM.addEventListener('mouseleave', removeHighlight);

// 保留原有的事件监听用于调试
const EVENTS = ["mouseup", "mousedown", "touchstart", "touchend", "click", "touchcancel", "mouseenter", "mouseout", "focusin"];
for (let e of EVENTS) {
  document.body.addEventListener(e, () => {Print(e)});
}
</script>
</body>
</html>

内容的提问来源于stack exchange,提问作者personal_cloud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 11:25:21