为什么touchstart事件在移动端触发后无法阻止默认行为?

W″翌喆 阅读 15

我在移动端开发时给按钮绑定了touchstart事件,想要阻止页面滑动的默认行为。代码是这样写的:


element.addEventListener('touchstart', (e) => {
  e.preventDefault();
  console.log('按钮被触摸');
});

但测试时发现页面仍然可以滑动,明明调用了preventDefault(),这是哪里出问题了?其他事件比如click正常触发,但需要兼容触摸操作。

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
Air-钰莹
你这个问题挺常见的。在移动端,touchstart事件里直接调用e.preventDefault()确实看起来应该能阻止默认行为,比如页面滑动,但实际上系统对这个事件的处理机制比较特殊。

问题出在浏览器对触摸事件的默认处理流程上。touchstart触发时,浏览器还没有确定是滚动还是点击,所以即使你在touchstart里调用了preventDefault(),也不能保证能阻止整个滑动行为。

要真正阻止滑动,建议你换个思路:监听touchmove事件,而不是touchstart。你可以在这个事件里做判断,比如只有在手指按下后移动的时候才阻止默认行为:

let isTouched = false;

element.addEventListener('touchstart', () => {
isTouched = true;
});

element.addEventListener('touchmove', (e) => {
if (isTouched) {
e.preventDefault();
console.log('阻止滑动');
}
});

element.addEventListener('touchend', () => {
isTouched = false;
});


这样做的原理是,在touchstart里做一个标记,表示开始触摸,然后在touchmove中根据这个标记决定是否阻止默认行为。

另外,如果你只是想阻止某些特定区域的滑动,可以在touchmove事件中加一个判断,看事件目标是否在你关心的区域内,这样就不会影响页面其他部分的滚动体验。

还有一点要注意:iOS 上有些行为是系统级的,比如双指缩放和滑动返回等,这些用preventDefault()是拦不住的,得靠 CSS 的 touch-action 属性来控制更稳妥。

总之,别指望靠一个touchstart里的preventDefault()就能搞定所有,默认行为的拦截要做得更精细一点。
点赞 4
2026-02-08 00:31