页面无法滚动_【前端词典】滚动穿透问题的解决方案
點擊上方“前端真好玩”,喜歡他就關(guān)注他
聽說,看愷哥的文章會上癮
背景
產(chǎn)品有三寶,彈窗,浮層加引導;
設計有三寶,透明,陰影加圓角;
運營有三寶,短信,推送加紅包;
程序員有一寶,這個做不了。
隨著移動端市場的份額越大,需求就越多樣化。我們今天討論的是移動端的滾動穿透問題。上面這段調(diào)侃的話可以看出需求中彈窗浮層還是挺常見的,那這個和滾動穿透有什么聯(lián)系呢?
我先解釋下什么是滾動穿透:
頁面滑出了一個彈窗,我們用手指觸摸屏幕滑動時,會發(fā)現(xiàn)彈窗下面的內(nèi)容還是在滾動。這個現(xiàn)象就是滾動穿透。
接下就說下我對滾動穿透問題解決方案探索的過程,希望對大家有點啟發(fā)。
需求
需求: 希望在點擊圖片的時候,從下方彈一個全屏的彈框來描述這張圖片的詳情。
方案
接到這個需求覺得沒有難度,很快就提測了,然后就開始逛逛掘金。可剛看大佬們的文章看的開心的時候,測試就在微信我。心想來 bug 了?突然意識到寫彈窗的時候忘記處理滾動穿透的問題了。記得第一次遇到這個問題的時候也是找了很久的資料。
方案一:
找到的第一個方法就是當彈窗觸發(fā)的時候,給 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 屬性值會變?yōu)?0。
這個新問題比起滾動穿透本身來說更加麻煩,所以這個方案是要進行優(yōu)化的。
方案二:
既然添加 modal_open 這個 class 會使 body 的滾動位置會丟失,那么我們?yōu)槭裁床辉跐L動位置丟失之前先保存下來,等到退出彈窗的前在將這個保存下來的滾動位置在設置回去。然后就朝著這個方向開始 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 事件;
方案二可以適應絕大多數(shù)的彈窗需求,提測后測試方也沒有在提其他問題,這個問題算是完美的解決了。不過我在這個過程有一個疑問:
IOS 自有的橡皮筋效果會導致頁面會出現(xiàn)短暫卡頓現(xiàn)象,暫時沒有找到原因,請教各位。
其他方案:
使用 preventDefault 阻止瀏覽器默認事件:
var modal = document.getElementById('modalBox');
modal.addEventListener('touchmove', function(e) {
e.preventDefault();
}, false);
這個方案只適用于這個彈窗本身的高度小于屏幕的高度,即不可滾動的時候。 touchmove 比 touchstart更加合適。因為 touchstart 會連點擊事件都阻止。
使用插件:
對于插件我的態(tài)度是,除非是自己實現(xiàn)起來太復雜,否則還是自己花點時間去實現(xiàn)。原因有二:
使用插件就意味著需要引入的文件至少多了一個。
插件過多,擔心日后項目升級維護成本加大。
以上。
參考
https://developer.mozilla.org/en-US/docs/Web/API/document/scrollingElement
https://uedsky.com/2016-06/mobile-modal-scroll/
前端詞典系列
《前端詞典》這個系列會持續(xù)更新,每一期我都會講一個出現(xiàn)頻率較高的知識點。希望大家在閱讀的過程當中可以斧正文中出現(xiàn)不嚴謹或是錯誤的地方,本人將不勝感激;若通過本系列而有所得,本人亦將不勝欣喜。
內(nèi)容: 前端以及網(wǎng)絡相關(guān)知識點的介紹并加以實際應用作為輔助。
目的: 這個系列的文章可以對讀者起到一點幫助,解開一些迷惑。
希望各位多指點一二,不吝賜教。
如果你覺得我的文章寫的還不錯,那就關(guān)注我唄!
"原創(chuàng)寫作,實屬不易,感謝支持"
總結(jié)
以上是生活随笔為你收集整理的页面无法滚动_【前端词典】滚动穿透问题的解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 360浏览器和chrome浏览器对于fl
- 下一篇: 前端将二进制数据流转为文件_前端通过二进