1、 问题
众所周知,移动端当有 fixed 遮罩背景和弹出层时,在屏幕上滑动能够滑动背景下面的内容,这就是臭名昭著的滚动穿透问题,下面是几种解决方案。
2、解决方案
-
&1 方案一:
当打开蒙层时,给html
和body
元素添加样式; 当关闭蒙层时,移除以上样式overflow: hidden; height: 100%;
缺点:
1、兼容性不好,部分安卓机型以及safari中,无法无法阻止底部页面滚动
2、由于 html 和 body的滚动条都被禁用,弹出层后页面的滚动位置会丢失,需要用 js 来还原
3、如果蒙层内容较高,也需要滚动,则无法实现对应需求-
&2 方案二:
利用移动端的touch事件,来阻止默认行为modal.addEventListener('touchmove', function(e) { e.preventDefault(); }, false);
缺点:
1、弹出层里不能有其它需要滚动的内容-
&3 方案三:
我们要阻止页面滚动,可以将其固定在视窗(即position: fixed),这样它就无法滚动了,当蒙层关闭时再释放。body.modal-open { position: fixed; width: 100%; }
但是这样会出现一个同样的问题,就是当前滚动条的位置同样会丢失,所以我们必须用js得到当前滚动条的位置手动设置,当隐藏蒙层时还原.如下
showModel() { let top = Tool.getScrollOffsets().y //获取滚动条高度 document.body.classList.add('modal-open') document.body.style.top = -top + 'px' ... } hideModel() { document.body.classList.remove('modal-open') document.body.style.top = 0 window.scroll(0,this.state.top) //回到原先的top }
完美解决