我们在做H5,或者App开发很多时候都会遇到一个问题,UI组件提供的弹窗满足不了需要,需要自定义弹窗,于是就自己搞了个蒙层,定位在body上面,然后在蒙层上面定义自己的弹窗,一切似乎非常简单,写完了调试你发现,怎么弹窗弹出了内容却还可以滚动?我遇到了这个问题,然后疯狂在网上找了好多demo,还是不能实现效果,把弹窗固定了,发现每次弹窗出现的时候页面总是滚动到顶部。这个就是万恶的穿透问题。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//禁止滑动事件
var ModalHelper = (function() {
var scrollTop;
return {
afterOpen: function() {
scrollTop = document.scrollingElement.scrollTop;
document.body.classList.add('modal-open');
//设置了固定定位属性之后滚动条会在顶部,需要用js还原滚动条原来的位置
document.body.style.top = -scrollTop + 'px';
},
beforeClose: function() {
document.body.classList.remove('modal-open');
// 取消了了position:fixed样式之后scrollTop属性就变成0了,要重新设置
document.scrollingElement.scrollTop = scrollTop;
}
};
})();

//打开弹窗
var openDialog = function() {
ModalHelper.afterOpen();
}

//关闭弹窗
var closeModal = function() {
ModalHelper.beforeClose();
}

还需要写上css的样式

1
2
3
4
.modal-open {
position: fixed;
width: 100%;
}

在这里获取滚动条高度使用了document.scrollingElement这个属性,旧属性scrollTop 存在兼容性,

参考文献

移动端滚动穿透问题完美解决方案

移动页面滚动穿透如何解决

document-scrollingElement相关文章

Chrome 中 scrollingElement 的变化

A polyfill for document.scrollingElement as defined in the CSSOM specification