定義:移動端彈出fixed彈窗的話,在彈窗上滑動會導(dǎo)致下層的頁面跟著滾動蠢甲,這個(gè)叫?“滾動穿透”
解決方案1
在彈出層的touchstart事件中調(diào)用preventDefault
這種方法不可取僵刮,至少有3個(gè)缺點(diǎn):
如果彈出層本身是有滾動(條)的話,將會導(dǎo)致彈出層無法滾動鹦牛,此時(shí)用這種方法無異于飲鴆止渴搞糕。
一個(gè)很常見的場景,點(diǎn)擊彈出層曼追,彈出層消失掉窍仰,此時(shí)也無法觸發(fā)彈出層的點(diǎn)擊回調(diào)事件。
彈出層內(nèi)的任何事件都執(zhí)行不了了拉鹃。
解決方案2
此解決方案是解決方案1的升級版辈赋。
在彈出層的touchmove(注意區(qū)別)事件中調(diào)用preventDefault
這種解決辦法沒有了第一種解決辦法的 2, 3 缺點(diǎn)。適用于彈出層本身有沒有滾動(條)膏燕。
解決方案3
設(shè)置body{overflow:hidden;}
js? ?彈窗顯示的時(shí)候設(shè)置為 document.querySelector("body").style.cssText="overflow:hidden"
? ? ? 彈窗隱藏的時(shí)候設(shè)置為?document.querySelector("body").style.cssText="overflow:auto"
缺點(diǎn):經(jīng)測試钥屈,在PC上支持良好,但是在IOS端坝辫,跟沒有設(shè)置是一樣的篷就,完全不起任何作用!近忙。
這種解決方案適用于PC端竭业。
解決方案4
設(shè)置 html,body{overflow:hidden;}
在PC和移動端都能禁止掉下層的滾動。
缺點(diǎn):
滾動位置丟失及舍!頁面會回到頂部未辆!
頁面的背景還是能夠有滾的動的效果(這個(gè)我沒遇到)。
可通過js來fix這個(gè)缺點(diǎn)锯玛,在彈出層出現(xiàn)時(shí)咐柜,記錄頁面的scrollTop兼蜈,當(dāng)彈出層消失時(shí),把先前記錄的scrollTop再次賦予頁面拙友。
終極完美解決方案
此解決方案能夠避免上述所有缺點(diǎn)为狸。堪稱完美遗契。
(這個(gè)方案會導(dǎo)致主頁面display:flex 的元素在彈框打開后消失)
css
body.dialog-open{position:fixed;width:100%;}
javascript
(function(){varscrollTop=0;//顯示彈出層open.onclick=function(){//在彈出層顯示之前辐棒,記錄當(dāng)前的滾動位置scrollTop=getScrollTop();//使body脫離文檔流document.body.classList.add('dialog-open');//把脫離文檔流的body拉上去!否則頁面會回到頂部牍蜂!document.body.style.top=-scrollTop+'px';mask.style.display='block';? }//隱藏彈出層close.onclick=function(){mask.style.display='none';//body又回到了文檔流中(我胡漢三又回來啦Q)document.body.classList.remove('dialog-open');//滾回到老地方to(scrollTop);? }functionto(scrollTop){document.body.scrollTop=document.documentElement.scrollTop=scrollTop;? }functiongetScrollTop(){returndocument.body.scrollTop||document.documentElement.scrollTop;? } }());
解決滾動穿透的2個(gè)工具方法:
functionfixedBody(){varscrollTop=document.body.scrollTop||document.documentElement.scrollTop;document.body.style.cssText+='position:fixed;top:-'+scrollTop+'px;';}functionlooseBody() {varbody=document.body;body.style.position='';vartop=body.style.top;document.body.scrollTop=document.documentElement.scrollTop=-parseInt(top);body.style.top='';}