长按手势在移动端怎么实现才不会和点击冲突?

夏侯静静 阅读 9

我在做一个移动端的图片列表,想给每个图片加个长按弹出菜单的功能,但发现长按的时候总会先触发 click 事件,体验很奇怪。试过用 touchstart 和 setTimeout 判断时间,但有时候还是会误触。

下面是我现在写的代码:

let pressTimer = null;
element.addEventListener('touchstart', () => {
  pressTimer = setTimeout(() => {
    console.log('长按触发');
  }, 600);
});
element.addEventListener('touchend', () => {
  clearTimeout(pressTimer);
});

这样写的话,短按还是会触发默认的 click,有没有办法彻底屏蔽掉?或者有更好的实现方式?

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
夏侯慧慧
你这个问题的核心是要区分短按和长按。我之前也被这个问题折磨过,后来发现关键在于要阻止默认行为。

试试这样改:

let pressTimer = null;
let isLongPress = false;

element.addEventListener('touchstart', (e) => {
isLongPress = false;
pressTimer = setTimeout(() => {
isLongPress = true;
console.log('长按触发');
}, 600);
});

element.addEventListener('touchend', (e) => {
clearTimeout(pressTimer);
if(isLongPress) {
e.preventDefault();
}
});

element.addEventListener('click', (e) => {
if(isLongPress) {
e.preventDefault();
e.stopPropagation();
isLongPress = false;
}
});


关键点有三个:
1. 用 isLongPress 标记状态
2. 在 touchend 里判断如果是长按就阻止默认行为
3. 在 click 事件里也要阻止,因为有些浏览器会冒泡触发

性能上这样处理没啥负担,就是多了个状态判断。实际测试发现 600ms 的延迟比较合适,苹果官方推荐也是这个值。

还有个坑要注意:如果用户手指移动了可能不算长按,可以再加个 touchmove 事件清除定时器,但我觉得大部分场景现在这样就够用了。
点赞 2
2026-03-08 21:12