移动端阻止默认滚动需在 touchstart/touchmove 中调用 preventDefault(),但须确保监听器设为 {passive: false};应精准控制区域与方向,避免全局禁用;iOS Safari 需用固定容器替代 body 操作;CSS 的 touch-action 和 overscroll-behavior 可辅助实现。

在移动端触摸事件中阻止默认滚动,关键是在 touchstart 或 touchmove 事件中调用 event.preventDefault(),但必须满足「事件处理器已绑定」且「未被 passive 触发」这两个前提。
确保事件监听器不是 passive
现代浏览器(Chrome 56+、Safari 15.4+ 等)对 touchstart 和 touchmove 默认启用 passive: true,此时调用 preventDefault() 会被忽略并报警告。解决方法是显式设置 { passive: false }:
element.addEventListener('touchmove', function (e) {
e.preventDefault(); // ✅ 生效
}, { passive: false });
只在需要时阻止,避免全局禁用
盲目阻止所有 touchmove 会导致页面完全无法滚动,应结合业务逻辑精准控制。常见做法有:
- 仅对特定区域(如轮播图容器、滑动菜单)阻止,默认允许 body 滚动
- 判断手势方向:横向滑动时阻止竖向滚动(
e.cancelable === true且Math.abs(dx) > Math.abs(dy)) - 使用标志位(如
isDragging)在touchstart设置,在touchend/touchcancel清除
兼容 iOS Safari 的额外注意点
iOS Safari 对 body 或 html 的触摸滚动限制更严格,直接在 document 上阻止可能无效。推荐做法:
立即学习“Java免费学习笔记(深入)”;
- 将可滚动内容包裹在固定高度 +
overflow-y: auto的容器内,并对该容器绑定touchmove - 避免在
body上设置touchmove.preventDefault(),它可能触发“弹性回弹失效”或卡顿 - 若需禁止整个页面滚动,可用
document.body.style.overflow = 'hidden'辅助(但需注意 viewport 高度变化)
替代方案:CSS 层面辅助控制
部分场景下,用 CSS 可减少 JS 干预:
-
touch-action: pan-x:允许水平滚动,禁止竖向滚动(适用于轮播图) -
touch-action: none:完全接管触摸行为(需配合 JS 处理所有手势) -
overscroll-behavior: contain:防止滚动穿透(比如弹层滚动到底后触发背景页滚动)


















