移动端弹窗打开后背景还能滚动怎么办?

Des.世杰 阅读 40

我在做移动端页面,弹出一个 fixed 定位的 modal 时,发现背后的页面还能上下滚动,体验很不好。试过给 body 加 overflow: hidden,但 iOS 上完全没用,还是能滑动,这咋整?

网上有人说要监听 touchmove 阻止默认行为,我试了下面这段代码,但好像也不太稳定:

document.body.style.overflow = 'hidden';
document.body.addEventListener('touchmove', (e) => {
  e.preventDefault();
}, { passive: false });
我来解答 赞 6 收藏
二维码
手机扫码查看
2 条解答
码农永穗
复制这个,试试这样解决:

document.body.style.overflow = 'hidden';
let startY = 0;

document.querySelector('.modal').addEventListener('touchstart', (e) => {
startY = e.touches[0].clientY;
});

document.querySelector('.modal').addEventListener('touchmove', (e) => {
const currentY = e.touches[0].clientY;
if (currentY > startY) {
e.preventDefault();
}
startY = currentY;
});


这段代码加了个简单的手势判断,阻止向下滚动时的默认行为。记得把 '.modal' 替换为你的实际 modal 类名或选择器。
点赞
2026-03-21 16:11
UX-俊衡
UX-俊衡 Lv1
这个问题我踩过三次坑才搞定,说多了都是泪。

iOS Safari 的 bug 就是这样:当你弹出 fixed 定位的弹窗时,光给 body 加 overflow: hidden 根本没用,它不吃这套。

最靠谱的解决方案是这样的:

打开弹窗时,给 body 加上 position: fixed:

body.modal-open {
overflow: hidden;
position: fixed;
width: 100%;
height: 100%;
}


然后在打开弹窗时给 body 加上这个 class,关闭时移除:

// 打开弹窗
document.body.classList.add('modal-open');

// 关闭弹窗
document.body.classList.remove('modal-open');


为什么要同时设置 width: 100% 和 height: 100%?因为加上 position: fixed 后 body 会丢失原本的高度,导致页面跳动一下。加上宽高能避免这个问题。

至于你试的那个 touchmove 监听,确实能兜底,但体验不好——弹窗里如果有自己的滚动区域,还得判断 target,代码写起来很麻烦。用 position: fixed 这种方案更干净利落。

如果你发现偶尔还是有问题(比如快速滑动时),可以在 body 的 class 上再加个 touch-action: none,不过一般情况上面这套就够了。
点赞 1
2026-03-11 06:00