移动端双击事件如何避免快速点击导致多次触发?

Designer°红娟 阅读 124

在移动端开发中,我给按钮绑定了双击事件,用touchstart记录时间差判断双击:


let lastTap = 0;
element.addEventListener('touchstart', () => {
  if (Date.now() - lastTap < 300) {
    console.log('双击触发');
  }
  lastTap = Date.now();
});

但发现当快速连点三次时,会错误触发两次双击事件。试过加防抖函数也没完全解决,有没有更可靠的双击检测方案?

我来解答 赞 20 收藏
二维码
手机扫码查看
2 条解答
秀兰
秀兰 Lv1
双击检测核心是控制好状态机,你的代码在连击三次时会触发两次双击,是因为没有限制双击触发后的冷却时间。

可以用一个 isDoubleTap 标志来判断是否已触发双击,并在触发后设置一个冷却期(如500ms),避免短时间内重复触发。

下面是我常用的方案,复制过去试试:


let lastTapTime = 0;
let isDoubleTap = false;

element.addEventListener('touchstart', () => {
const now = Date.now();

if (now - lastTapTime < 300) {
if (!isDoubleTap) {
console.log('双击触发');
isDoubleTap = true;

// 双击后进入冷却期,防止误触发
setTimeout(() => {
isDoubleTap = false;
}, 500);
}
} else {
isDoubleTap = false;
}

lastTapTime = now;
});


这样改完后,即使快速点击三次,中间的点击也不会再次触发双击事件,直到冷却期结束。比单纯的防抖更稳定,适合用于按钮、图片缩放等场景。
点赞 7
2026-02-03 13:05
开发者鑫玉
这个问题我也踩过坑,确实用简单的时间差判断很容易出错,特别是快速连点时。血泪教训告诉我,得用标志位来控制事件状态。

你可以试试这样:

let lastTap = 0;
let isDoubleTap = false;

element.addEventListener('touchstart', (e) => {
if (isDoubleTap) {
console.log('双击触发');
isDoubleTap = false; // 重置标志位
return;
}

let now = Date.now();
if (now - lastTap < 300) {
isDoubleTap = true; // 标记为可能的双击
} else {
isDoubleTap = false; // 不是双击就重置
}

lastTap = now;

// 防止单击逻辑干扰
setTimeout(() => {
if (!isDoubleTap) {
console.log('单击触发');
}
}, 300);
});


关键点就是加了个isDoubleTap标志位,用来区分到底是不是双击。这样即使用户快速连点三次,也不会误判成两次双击了。

这个方案我用过几次,基本没再出问题。不过移动端事件有时候还是挺诡异的,如果还有特殊情况可以再调调时间间隔。
点赞 9
2026-02-01 12:11