滾動穿透的兩種解決方案

滾動穿透:頁面滑出了一個彈窗,我們用手指觸摸屏幕滑動時,會發現彈窗下面的內容還是在滾動。

方案一:

找到的第一個方法就是當彈窗觸發的時候,給 overflow: scroll: 的元素加上一個 class (一般都是 body 元素)。退出的時候去掉這個 class。下面爲了方便,會直接用 body 元素來代指彈窗下方的元素。

// css 部分
modal_open {
    position: fixed;
    height: 100%;
}

// js 部分
document.body.classList.add('modal_open');
document.body.classList.remove('modal_open');

上面的這個方法可以解決滾動穿透問題,卻也會帶來新的問題。
即:

body 的滾動位置會丟失,也就是body 的 scrollTop 屬性值會變爲 0。

這個新問題比起滾動穿透本身來說更加麻煩,所以這個方案是要進行優化的。

方案二:

既然添加 modal_open 這個 class 會使 body 的滾動位置會丟失,那麼我們爲什麼不在滾動位置丟失之前先保存下來,等到退出彈窗的前在將這個保存下來的滾動位置在設置回去。然後就朝着這個方向開始 coding 。

// css 部分
.modal_open {
  position: fixed;
  height: 100%;
}

// js 部分
/**
 * ModalHelper helpers resolve the modal scrolling issue on mobile devices
 * https://github.com/twbs/bootstrap/issues/15852
 */
var ModalHelper = (function(bodyClass) {
    var scrollTop;
    return {
        afterOpen: function() {
            scrollTop = document.scrollingElement.scrollTop  ||
                        document.documentElement.scrollTop || 
                        document.body.scrollTop;
            document.body.classList.add(bodyClass);
            document.body.style.top = -scrollTop + 'px';
        },
        beforeClose: function() {
            document.body.classList.remove(bodyClass);
            document.scrollingElement.scrollTop = document.documentElement.scrollTop = document.body.scrollTop = scrollTop;
        }
    };
})('modal_open');

// method
modalSwitch: function(){
    let self = this;
    if( self.switchFlag === 'close' ){
        ModalHelper.afterOpen();
        self.switchFlag = 'open';
    }else{
        ModalHelper.beforeClose();
        self.switchFlag = 'close';
    }
}

方案二可以達到以下效果:

彈窗滾動的時候,下方的 body 是固定的無法滾動;
body 的滾動位置不會丟失;
body 有 scroll 事件;

方案二可以適應絕大多數的彈窗需求,提測後測試方也沒有在提其他問題,這個問題算是完美的解決了。

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