DoubleTap 手势在移动端怎么监听才有效?

司马涵菲 阅读 8

我在用原生 JS 做一个移动端图片预览功能,想通过双击放大图片,但试了 touchstart 和 click 都没法准确识别双击。网上说要用时间间隔判断,但我写的逻辑好像有冲突。

比如我这样记录两次点击时间:const now = Date.now(); if (now - lastTap < 300) { /* 双击 */ },结果经常误触发,或者跟缩放手势打架,到底该怎么处理才靠谱?

我来解答 赞 1 收藏
二维码
手机扫码查看
2 条解答
树萱的笔记
用 setTimeout 清理上次点击,300ms 阈值,加上 touchcancel 处理冲突就行了。代码:

let lastTap = 0;
const delay = 300;
element.addEventListener('touchend', (e) => {
const now = Date.now();
if (now - lastTap < delay) {
e.preventDefault();
// 双击逻辑
}
lastTap = now;
});
element.addEventListener('touchcancel', () => lastTap = 0);
点赞 1
2026-03-06 18:14
春莉的笔记
移动端双击检测确实坑多,搞不好就会和手势冲突。我给你个优化过的方案,性能上比直接比较时间戳更可靠。

核心要点:用 setTimeout 清除标记 + 区分 touch 和 click 事件。别混用 touch 和 click,选一种就行:

let lastTap = 0;
let timer;

element.addEventListener('touchstart', (e) => {
const now = Date.now();
if (now - lastTap < 300) {
clearTimeout(timer);
handleDoubleTap(e);
return;
}

timer = setTimeout(() => {
clearTimeout(timer);
}, 300);
lastTap = now;
});

function handleDoubleTap(e) {
// 这里记得阻止默认行为,防止和缩放冲突
e.preventDefault();
// 你的放大逻辑
}


几个关键点:
1. 用 clearTimeout 清理上次的定时器,避免误触发
2. 300ms 是经验值,可以根据设备调整
3. 一定要 preventDefault,否则会和浏览器默认手势打架

实测这套逻辑在 iOS 和 Android 上都比较稳,误触发少。如果还有问题,可能是外层元素的事件冒泡没处理好。
点赞 1
2026-03-05 11:03