摘要:接下就說(shuō)下我對(duì)滾動(dòng)穿透問(wèn)題解決方案探索的過(guò)程,希望對(duì)大家有點(diǎn)啟發(fā)。心想來(lái)了突然意識(shí)到寫(xiě)彈窗的時(shí)候忘記處理滾動(dòng)穿透的問(wèn)題了。下期預(yù)告前端詞典繼承必懂知識(shí)點(diǎn)傳送門(mén)前端詞典代理的概念及其應(yīng)用前端詞典滾動(dòng)穿透問(wèn)題的解決方案
背景
產(chǎn)品有三寶,彈窗,浮層加引導(dǎo);
設(shè)計(jì)有三寶,透明,陰影加圓角;
運(yùn)營(yíng)有三寶,短信,推送加紅包;
程序員有一寶,這個(gè)做不了。
隨著移動(dòng)端市場(chǎng)的份額越大,需求就越多樣化。我們今天討論的是移動(dòng)端的滾動(dòng)穿透問(wèn)題。上面這段調(diào)侃的話可以看出需求中彈窗浮層還是挺常見(jiàn)的,那這個(gè)和滾動(dòng)穿透有什么聯(lián)系呢?
我先解釋下什么是滾動(dòng)穿透:
頁(yè)面滑出了一個(gè)彈窗,我們用手指觸摸屏幕滑動(dòng)時(shí),會(huì)發(fā)現(xiàn)彈窗下面的內(nèi)容還是在滾動(dòng)。這個(gè)現(xiàn)象就是滾動(dòng)穿透。
接下就說(shuō)下我對(duì)滾動(dòng)穿透問(wèn)題解決方案探索的過(guò)程,希望對(duì)大家有點(diǎn)啟發(fā)。
需求需求: 希望在點(diǎn)擊圖片的時(shí)候,從下方彈一個(gè)全屏的彈框來(lái)描述這張圖片的詳情。方案
接到這個(gè)需求覺(jué)得沒(méi)有難度,很快就提測(cè)了,然后就開(kāi)始逛逛掘金??蓜偪创罄袀兊奈恼驴吹拈_(kāi)心的時(shí)候,測(cè)試就在微信我。心想來(lái) bug 了?
突然意識(shí)到寫(xiě)彈窗的時(shí)候忘記處理滾動(dòng)穿透的問(wèn)題了。記得第一次遇到這個(gè)問(wèn)題的時(shí)候也是找了很久的資料。
找到的第一個(gè)方法就是當(dāng)彈窗觸發(fā)的時(shí)候,給 overflow: scroll: 的元素加上一個(gè) class (一般都是 body 元素)。退出的時(shí)候去掉這個(gè) class。下面為了方便,會(huì)直接用 body 元素來(lái)代指彈窗下方的元素。
// css 部分 modal_open { position: fixed; height: 100%; } // js 部分 document.body.classList.add("modal_open"); document.body.classList.remove("modal_open");
上面的這個(gè)方法可以解決滾動(dòng)穿透問(wèn)題,卻也會(huì)帶來(lái)新的問(wèn)題。
即:
body 的滾動(dòng)位置會(huì)丟失,也就是body 的 scrollTop 屬性值會(huì)變?yōu)?0。
這個(gè)新問(wèn)題比起滾動(dòng)穿透本身來(lái)說(shuō)更加麻煩,所以這個(gè)方案是要進(jìn)行優(yōu)化的。
方案二:既然添加 modal_open 這個(gè) class 會(huì)使 body 的滾動(dòng)位置會(huì)丟失,那么我們?yōu)槭裁床辉跐L動(dòng)位置丟失之前先保存下來(lái),等到退出彈窗的前在將這個(gè)保存下來(lái)的滾動(dòng)位置在設(shè)置回去。然后就朝著這個(gè)方向開(kāi)始 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"; } }
方案二可以達(dá)到以下效果:
彈窗滾動(dòng)的時(shí)候,下方的 body 是固定的無(wú)法滾動(dòng);
body 的滾動(dòng)位置不會(huì)丟失;
body 有 scroll 事件;
方案二可以適應(yīng)絕大多數(shù)的彈窗需求,提測(cè)后測(cè)試方也沒(méi)有在提其他問(wèn)題,這個(gè)問(wèn)題算是完美的解決了。不過(guò)我在這個(gè)過(guò)程有一個(gè)疑問(wèn):
IOS 自有的橡皮筋效果會(huì)導(dǎo)致頁(yè)面會(huì)出現(xiàn)短暫卡頓現(xiàn)象,暫時(shí)沒(méi)有找到原因,請(qǐng)教各位。其他方案:
使用 preventDefault 阻止瀏覽器默認(rèn)事件:
var modal = document.getElementById("modalBox"); modal.addEventListener("touchmove", function(e) { e.preventDefault(); }, false);
這個(gè)方案只適用于這個(gè)彈窗本身的高度小于屏幕的高度,即不可滾動(dòng)的時(shí)候。touchmove 比 touchstart 更加合適。因?yàn)?touchstart 會(huì)連點(diǎn)擊事件都阻止。
使用插件:
對(duì)于插件我的態(tài)度是,除非是自己實(shí)現(xiàn)起來(lái)太復(fù)雜,否則還是自己花點(diǎn)時(shí)間去實(shí)現(xiàn)。原因有二:
使用插件就意味著需要引入的文件至少多了一個(gè)。
插件過(guò)多,擔(dān)心日后項(xiàng)目升級(jí)維護(hù)成本加大。
以上。
參考https://developer.mozilla.org/en-US/docs/Web/API/document/scrollingElement
https://uedsky.com/2016-06/mobile-modal-scroll/
前端詞典系列《前端詞典》這個(gè)系列會(huì)持續(xù)更新,每一期我都會(huì)講一個(gè)出現(xiàn)頻率較高的知識(shí)點(diǎn)。希望大家在閱讀的過(guò)程當(dāng)中可以斧正文中出現(xiàn)不嚴(yán)謹(jǐn)或是錯(cuò)誤的地方,本人將不勝感激;若通過(guò)本系列而有所得,本人亦將不勝欣喜。
內(nèi)容: 前端以及網(wǎng)絡(luò)相關(guān)知識(shí)點(diǎn)的介紹并加以實(shí)際應(yīng)用作為輔助。
目的: 這個(gè)系列的文章可以對(duì)讀者起到一點(diǎn)幫助,解開(kāi)一些迷惑。
希望各位多指點(diǎn)一二,不吝賜教。
下期預(yù)告【前端詞典】繼承 - JavaScript 必懂知識(shí)點(diǎn)
傳送門(mén)【前端詞典】代理的概念及其應(yīng)用
【前端詞典】滾動(dòng)穿透問(wèn)題的解決方案
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/117201.html
摘要:接下就說(shuō)下我對(duì)滾動(dòng)穿透問(wèn)題解決方案探索的過(guò)程,希望對(duì)大家有點(diǎn)啟發(fā)。心想來(lái)了突然意識(shí)到寫(xiě)彈窗的時(shí)候忘記處理滾動(dòng)穿透的問(wèn)題了。下期預(yù)告前端詞典繼承必懂知識(shí)點(diǎn)傳送門(mén)前端詞典代理的概念及其應(yīng)用前端詞典滾動(dòng)穿透問(wèn)題的解決方案 背景 產(chǎn)品有三寶,彈窗,浮層加引導(dǎo); 設(shè)計(jì)有三寶,透明,陰影加圓角; 運(yùn)營(yíng)有三寶,短信,推送加紅包; 程序員有一寶,這個(gè)做不了。 隨著移動(dòng)端市場(chǎng)的份額越大,需求就越多...
摘要:用于獲得當(dāng)前元素到定位父級(jí)頂部的距離偏移值。后來(lái)在項(xiàng)目中總會(huì)遇到滾動(dòng)吸頂?shù)男Ч枰獙?shí)現(xiàn),現(xiàn)在我將我知道的種滾動(dòng)吸頂實(shí)現(xiàn)方式做詳細(xì)介紹。有兼容性問(wèn)題,在微信瀏覽器某些版本中的值會(huì)為,于是乎也就有了第三種方案的兼容性寫(xiě)法。修改版預(yù)覽 這篇文章是三天前寫(xiě)就的,有大佬給我提了一些修改意見(jiàn),我覺(jué)得這個(gè)意見(jiàn)確實(shí)中肯。所以就有了這個(gè)升級(jí)的修改版本。代碼同步更新到 GitHub 了。 修改內(nèi)容如下: 添加...
摘要:第一篇文章我會(huì)結(jié)合和的部分源碼,來(lái)說(shuō)明注入生命周期的過(guò)程。說(shuō)到源碼,其實(shí)沒(méi)有想象的那么難。但是源碼的調(diào)用樹(shù)會(huì)復(fù)雜很多。應(yīng)用的業(yè)務(wù)代碼逐漸復(fù)雜,事件事件總線等通信的方式的弊端就會(huì)愈發(fā)明顯。狀態(tài)管理是組件解耦的重要手段。前言 這篇文章是【前端詞典】系列文章的第 13 篇文章,接下的 9 篇我會(huì)圍繞著 Vue 展開(kāi),希望這 9 篇文章可以使大家加深對(duì) Vue 的了解。當(dāng)然這些文章的前提是默認(rèn)你對(duì) ...
摘要:于是帶著以下兩個(gè)問(wèn)題開(kāi)始學(xué)習(xí)正向代理以及反向代理??蛻?hù)端才能使用正向代理。傳送門(mén)前端詞典代理的概念及其應(yīng)用前端詞典滾動(dòng)穿透問(wèn)題的解決方案 前言 在平時(shí)的工作中,總是會(huì)遇到代理的概念。之前我只知道有代理這個(gè)概念,不過(guò)對(duì)其沒(méi)有一個(gè)清晰的理解。于是帶著以下兩個(gè)問(wèn)題開(kāi)始學(xué)習(xí)正向代理以及反向代理。 什么是正向代理,什么是反向代理 正向代理可以做什么,反向代理可以做什么 概念 首先附上一張說(shuō)明...
摘要:于是帶著以下兩個(gè)問(wèn)題開(kāi)始學(xué)習(xí)正向代理以及反向代理??蛻?hù)端才能使用正向代理。傳送門(mén)前端詞典代理的概念及其應(yīng)用前端詞典滾動(dòng)穿透問(wèn)題的解決方案 前言 在平時(shí)的工作中,總是會(huì)遇到代理的概念。之前我只知道有代理這個(gè)概念,不過(guò)對(duì)其沒(méi)有一個(gè)清晰的理解。于是帶著以下兩個(gè)問(wèn)題開(kāi)始學(xué)習(xí)正向代理以及反向代理。 什么是正向代理,什么是反向代理 正向代理可以做什么,反向代理可以做什么 概念 首先附上一張說(shuō)明...
閱讀 3479·2021-11-12 10:36
閱讀 2826·2021-11-11 16:55
閱讀 3053·2021-09-27 13:36
閱讀 1678·2021-08-05 10:01
閱讀 3633·2019-08-30 15:55
閱讀 841·2019-08-30 13:01
閱讀 1965·2019-08-29 17:16
閱讀 2427·2019-08-29 16:40