长按手势在移动端怎么实现才不会和点击冲突?
我在做一个移动端的图片列表,想给每个图片加个长按弹出菜单的功能,但发现长按的时候总会先触发 click 事件,体验很奇怪。试过用 touchstart 和 setTimeout 判断时间,但有时候还是会误触。
下面是我现在写的代码:
let pressTimer = null;
element.addEventListener('touchstart', () => {
pressTimer = setTimeout(() => {
console.log('长按触发');
}, 600);
});
element.addEventListener('touchend', () => {
clearTimeout(pressTimer);
});
这样写的话,短按还是会触发默认的 click,有没有办法彻底屏蔽掉?或者有更好的实现方式?
最简单的办法是在 touchend 里加个判断:如果确实是长按触发了,就阻止默认行为。另外建议加上 touchmove 的监听,在用户移动手指时直接取消计时器,这样能避免误触。
给你个改进版代码:
这个方案在多个项目里验证过,基本不会有误触发问题。后端这边倒没什么特别需要注意的,主要就是前端这块的交互细节要处理好。记得测试不同机型和浏览器,毕竟移动端环境挺复杂的。
试试这样改:
关键点有三个:
1. 用 isLongPress 标记状态
2. 在 touchend 里判断如果是长按就阻止默认行为
3. 在 click 事件里也要阻止,因为有些浏览器会冒泡触发
性能上这样处理没啥负担,就是多了个状态判断。实际测试发现 600ms 的延迟比较合适,苹果官方推荐也是这个值。
还有个坑要注意:如果用户手指移动了可能不算长按,可以再加个 touchmove 事件清除定时器,但我觉得大部分场景现在这样就够用了。