⏱️ 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';
});