⏱️ 300ms 点击延迟与解决方案

移动端浏览器为了区分「单击」和「双击缩放」,会在 touchend 后等待约 300ms 才触发 click 事件。这导致交互有卡顿感。

解决方案对比

方案原理推荐度
① Viewport 禁止缩放 user-scalable=no 告诉浏览器无需等待双击 ⭐⭐⭐⭐
② FastClick 库 监听 touchend,立即触发 click 事件 ⭐⭐⭐(老旧方案)
③ touch-action CSS touch-action: manipulation 禁用双击缩放 ⭐⭐⭐⭐⭐
④ 直接用 touch 事件 用 touchend 替代 click 处理交互 ⭐⭐⭐

推荐做法:touch-action + Viewport

/* ===== CSS 方式:消除 300ms 延迟 ===== */
/* 全局设置,适合应用型页面 */
html {
  touch-action: manipulation;
}

/* 针对特定交互元素 */
button, a, .clickable {
  touch-action: manipulation;
}

点击穿透问题

当上层元素在 touchend 后消失(如遮罩层关闭),300ms 后触发的 click 会落在下层元素上,造成"穿透点击"。

// ===== 解决点击穿透的三种方式 =====

// 方式一:阻止默认行为 + 阻止冒泡
mask.addEventListener('touchend', (e) => {
  e.preventDefault();  // 阻止后续 click
  mask.style.display = 'none';
});

// 方式二:延迟隐藏(等待 click 完成)
mask.addEventListener('touchend', () => {
  setTimeout(() => { mask.style.display = 'none'; }, 350);
});

// 方式三:使用 touch-action + pointer-events
mask.addEventListener('touchend', () => {
  mask.style.pointerEvents = 'none'; // 下层收不到事件
  // 需要时再恢复: mask.style.pointerEvents = 'auto';
});