开发Cuteen时,侧边栏再一次遇到了滚动穿透问题。话说这个移动端滚动穿透问题很早就遇到了,当时采用的是弹出框出现时,记录滚动位置并让body禁止滚动,弹出框消失时,body滚动到记忆位置,但是弹出框是居中的一小块,其余部分使用黑色半透明的遮罩蒙版覆盖,所以弹出框时用户还是可以看见列表位置变成第一列,弹出框消失时列表又变到记忆位置,这样的体验非常不好,今天利用新方法,顺利解决了这个问题,顺便在此记录一下处理方法,希望能帮到需要帮助的人:
1.更换滚动dom的方法
经测试,当body滚动时,操作弹出层才会触发body的滚动,如果是其他dom滚动的话,在操作弹出层的时候不会触发该dom的滚动,所以把滚动内容的容器改成其他dom就可以了,如下:
<body>
<ui-view class="container" style="display: block; height: 100%; overflow: auto"></ui-view>
<div id="showDetail"></div>
</body>
这种办法最是简单有效,但是有可能和手势组件冲突,最后我使用的是下面这种方法:
2.移动body
这个方法来自:移动端滚动穿透问题完美解决方案
思路是弹出框弹出前,记录目前滚动位置,给body加上position: fixed;
然后使body的top距离为负的滚动距离即可(使屏幕显示的区域不变);弹出框消失时,移除position: fixed;
,设置body滚动位置为记录位置,这样就解决了我开头提到的位置跳转的问题:屏幕显示的内容始终不变,体验效果棒棒的
Css部分:
body.modal-open {
position: fixed;
width: 100%;
}
Js部分:
var ModalHelper = (function(bodyCls) {
var scrollTop;
return {
afterOpen: function() {
scrollTop = document.scrollingElement.scrollTop;
document.body.classList.add(bodyCls);
document.body.style.top = -scrollTop + 'px';
},
beforeClose: function() {
document.body.classList.remove(bodyCls);
// scrollTop lost after set position:fixed, restore it back.
document.scrollingElement.scrollTop = scrollTop;
}
};
})('modal-open');
3.利用属性 overflow: hidden
这个就是我原来采用的方法:
.no-scroll {
overflow: hidden;
height: 100%;
}
页面弹出层上将 .no-scroll
添加到 html 上,禁用 html 和 body 的滚动条,使用js来记录滚动位置,弹出框关闭时还原,不建议采用。
4.利用 touchmove + preventDefault
这种也是简单快速的处理办法,直接接听弹出层dom的touchmove
事件,然后阻止默认行为即可,但是这种方法使得弹出层dom的滚动事件也一并失效,所以当你的弹出层无需滚动时,这不失是一种快捷有效的方法:
modal.addEventListener('touchmove', function(e) {
e.preventDefault();
}, false);
完美解决问题,感谢博主