摘要:接下就說下我對滾動穿透問題解決方案探索的過程,希望對大家有點啟發。心想來了突然意識到寫彈窗的時候忘記處理滾動穿透的問題了。下期預告前端詞典繼承必懂知識點傳送門前端詞典代理的概念及其應用前端詞典滾動穿透問題的解決方案
背景
產品有三寶,彈窗,浮層加引導;
設計有三寶,透明,陰影加圓角;
運營有三寶,短信,推送加紅包;
程序員有一寶,這個做不了。
隨著移動端市場的份額越大,需求就越多樣化。我們今天討論的是移動端的滾動穿透問題。上面這段調侃的話可以看出需求中彈窗浮層還是挺常見的,那這個和滾動穿透有什么聯系呢?
我先解釋下什么是滾動穿透:
頁面滑出了一個彈窗,我們用手指觸摸屏幕滑動時,會發現彈窗下面的內容還是在滾動。這個現象就是滾動穿透。
接下就說下我對滾動穿透問題解決方案探索的過程,希望對大家有點啟發。
需求需求: 希望在點擊圖片的時候,從下方彈一個全屏的彈框來描述這張圖片的詳情。方案
接到這個需求覺得沒有難度,很快就提測了,然后就開始逛逛掘金。可剛看大佬們的文章看的開心的時候,測試就在微信我。心想來 bug 了?
突然意識到寫彈窗的時候忘記處理滾動穿透的問題了。記得第一次遇到這個問題的時候也是找了很久的資料。
找到的第一個方法就是當彈窗觸發的時候,給 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 事件;
方案二可以適應絕大多數的彈窗需求,提測后測試方也沒有在提其他問題,這個問題算是完美的解決了。不過我在這個過程有一個疑問:
IOS 自有的橡皮筋效果會導致頁面會出現短暫卡頓現象,暫時沒有找到原因,請教各位。其他方案:
使用 preventDefault 阻止瀏覽器默認事件:
var modal = document.getElementById("modalBox"); modal.addEventListener("touchmove", function(e) { e.preventDefault(); }, false);
這個方案只適用于這個彈窗本身的高度小于屏幕的高度,即不可滾動的時候。touchmove 比 touchstart 更加合適。因為 touchstart 會連點擊事件都阻止。
使用插件:
對于插件我的態度是,除非是自己實現起來太復雜,否則還是自己花點時間去實現。原因有二:
使用插件就意味著需要引入的文件至少多了一個。
插件過多,擔心日后項目升級維護成本加大。
以上。
參考https://developer.mozilla.org/en-US/docs/Web/API/document/scrollingElement
https://uedsky.com/2016-06/mobile-modal-scroll/
前端詞典系列《前端詞典》這個系列會持續更新,每一期我都會講一個出現頻率較高的知識點。希望大家在閱讀的過程當中可以斧正文中出現不嚴謹或是錯誤的地方,本人將不勝感激;若通過本系列而有所得,本人亦將不勝欣喜。
內容: 前端以及網絡相關知識點的介紹并加以實際應用作為輔助。
目的: 這個系列的文章可以對讀者起到一點幫助,解開一些迷惑。
希望各位多指點一二,不吝賜教。
下期預告【前端詞典】繼承 - JavaScript 必懂知識點
傳送門【前端詞典】代理的概念及其應用
【前端詞典】滾動穿透問題的解決方案
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100824.html
摘要:接下就說下我對滾動穿透問題解決方案探索的過程,希望對大家有點啟發。心想來了突然意識到寫彈窗的時候忘記處理滾動穿透的問題了。下期預告前端詞典繼承必懂知識點傳送門前端詞典代理的概念及其應用前端詞典滾動穿透問題的解決方案 背景 產品有三寶,彈窗,浮層加引導; 設計有三寶,透明,陰影加圓角; 運營有三寶,短信,推送加紅包; 程序員有一寶,這個做不了。 隨著移動端市場的份額越大,需求就越多...
摘要:用于獲得當前元素到定位父級頂部的距離偏移值。后來在項目中總會遇到滾動吸頂的效果需要實現,現在我將我知道的種滾動吸頂實現方式做詳細介紹。有兼容性問題,在微信瀏覽器某些版本中的值會為,于是乎也就有了第三種方案的兼容性寫法。修改版預覽 這篇文章是三天前寫就的,有大佬給我提了一些修改意見,我覺得這個意見確實中肯。所以就有了這個升級的修改版本。代碼同步更新到 GitHub 了。 修改內容如下: 添加...
摘要:第一篇文章我會結合和的部分源碼,來說明注入生命周期的過程。說到源碼,其實沒有想象的那么難。但是源碼的調用樹會復雜很多。應用的業務代碼逐漸復雜,事件事件總線等通信的方式的弊端就會愈發明顯。狀態管理是組件解耦的重要手段。前言 這篇文章是【前端詞典】系列文章的第 13 篇文章,接下的 9 篇我會圍繞著 Vue 展開,希望這 9 篇文章可以使大家加深對 Vue 的了解。當然這些文章的前提是默認你對 ...
摘要:于是帶著以下兩個問題開始學習正向代理以及反向代理。客戶端才能使用正向代理。傳送門前端詞典代理的概念及其應用前端詞典滾動穿透問題的解決方案 前言 在平時的工作中,總是會遇到代理的概念。之前我只知道有代理這個概念,不過對其沒有一個清晰的理解。于是帶著以下兩個問題開始學習正向代理以及反向代理。 什么是正向代理,什么是反向代理 正向代理可以做什么,反向代理可以做什么 概念 首先附上一張說明...
摘要:于是帶著以下兩個問題開始學習正向代理以及反向代理。客戶端才能使用正向代理。傳送門前端詞典代理的概念及其應用前端詞典滾動穿透問題的解決方案 前言 在平時的工作中,總是會遇到代理的概念。之前我只知道有代理這個概念,不過對其沒有一個清晰的理解。于是帶著以下兩個問題開始學習正向代理以及反向代理。 什么是正向代理,什么是反向代理 正向代理可以做什么,反向代理可以做什么 概念 首先附上一張說明...
閱讀 889·2023-04-26 02:16
閱讀 1198·2019-08-30 15:55
閱讀 2788·2019-08-30 15:53
閱讀 3382·2019-08-29 15:38
閱讀 2884·2019-08-29 13:42
閱讀 1980·2019-08-26 13:34
閱讀 1833·2019-08-26 10:10
閱讀 3077·2019-08-23 14:40