出处:掘金
原作者:江城开朗的豌豆
为什么会有 300ms 延迟?
在移动端,为了让用户能双击缩放(Double Tap to Zoom),浏览器在点击事件上设置了一个 300ms 的等待期,用户点了之后,浏览器会先等 300ms,确认没有第二次点击后,才触发事件
问题:按钮点击反应慢
如何干掉这 300ms 延迟?
1. 使用 touchstart
替代 click
(慎用!)
button.addEventListener('touchstart', () => {
console.log('这次反应够快了吧!');
});
- 优点:瞬间触发,没有延迟
- 缺点:
touchstart
会在手指刚触碰屏幕时就触发,可能导致误触(比如用户只是想滑动,却误点了按钮)
2. 设置 <meta>
标签,禁止缩放
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
这样浏览器就知道这个页面不需要双击缩放,自然就不会有 300ms 延迟了
- 适用场景:纯交互型 H5 页面,不需要缩放功能
3. 使用 FastClick 库(经典方案)
// 安装:npm install fastclick
import FastClick from 'fastclick';
FastClick.attach(document.body);
- 原理:用
touch
事件模拟click
,并立即触发,绕过浏览器的等待机制 - 适用场景:需要兼容老项目,或者不想手动处理
touch
事件的情况
4. 直接使用 CSS 的 touch-action
(现代浏览器推荐)
button {
touch-action: manipulation; /* 告诉浏览器:这个元素只允许滚动和连续触摸,不需要双击缩放 */
}
- 优点:纯 CSS 方案,无需 JS,性能更好
- 兼容性:现代浏览器基本都支持,IE 不行
为什么现在很多项目不用管 300ms 问题了?
随着移动端生态的成熟,现代浏览器(Chrome、Safari等)在 2015 年后逐步优化了这一机制:
- 如果页面设置了
<meta viewport>
且width=device-width
,大部分浏览器会自动禁用 300ms 延迟 - 新版 Chrome 和 Firefox 在移动端已经默认去除了延迟
但如果你的用户还在用老版本浏览器(比如某些国产安卓机的内置浏览器),可能还是会有这个问题
总结:如何优雅处理点击延迟?
- 优先使用
<meta viewport>
+touch-action: manipulation
(最简单、性能最好) - 如果需要兼容老旧设备,可以用 FastClick
- 除非特殊需求,别用
touchstart
替代click
,容易引发误触问题