modal 弹出层后禁止底层滚动

看到一篇不错的介绍由弹出层引发对滚动原理的讨论

亲自实验的时候各种坑,都知道在web上处理很简单:

html, body{
    overflow: hidden;
    height: 100%;
}

1.这样只能解决web上的问题,移动端不管用
2.这样处理仍然会有一些页面宽度适配问题


因为我用在微信公众号开发上(移动端),所以找移动端解决方案,
大部分回答是在弹出层弹出的时候禁用掉触摸事件,弹出层消失的时候再把事件加上:

// 记录原来的事件函数,以便恢复
var oldonwheel, oldonmousewheel, oldonkeydown, oldontouchmove;
var isDisabled;

function preventDefault(e) {
    e = e || window.event;
    e.preventDefault && e.preventDefault();
    e.returnValue = false;
}

var disableScroll = function(){
    oldonwheel = window.onwheel;
    window.onwheel = preventDefault;

    oldonmousewheel = window.onmousewheel;
    window.onmousewheel = preventDefault;

    oldonkeydown = document.onkeydown;
    document.onkeydown = preventDefaultForScrollKeys;

    oldontouchmove = window.ontouchmove;
    window.ontouchmove = preventDefault;

    isDisabled = true;
};

var enableScroll = function(){
    if(!isDisabled){
        return;
    }

    window.onwheel = oldonwheel;
    window.onmousewheel = oldonmousewheel;
    document.onkeydown = oldonkeydown;

    window.ontouchmove = oldontouchmove;
    isDisabled = false;
};

对于modal中不用滚动的页面来说的确可以解决问题,但是如果modal中内容也需要滚动,就不行了


最终解决方案:

弹出层父元素设置属性为overflow-y:scroll;
弹窗弹出时,用js控制让底层元素的position属性设置为fixed;
弹窗关闭时候,用js控制底层元素的position属性为正常;
在iOS端,为了弹窗里面的滚动效果看起来顺滑,需要设置弹窗层的包裹元素属性:-webkit-overflow-scrolling : touch; 

其实还是存在一点小问题,就是弹出层消失的时候,底层页面会自动滚动到顶部,我们可以在弹出层弹出的时候记录一下当前位置,然后在弹出层消失的时候js控制滚动到之前的位置

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章