摘要:起因最近幾天在寫一個滾動加載更多數據的插件,為局部滾動寫時,遇到了很多局部滾動的坑,在這里分享一下這些坑的解決方案。約定把產生滾動條的元素稱之為視窗全局滾動滾動條在或者父級元素上。坑一瀏覽器局部滾動默認沒有彈性滾動的效果。
起因
最近幾天在寫一個滾動加載更多數據的插件(Scrollload),為局部滾動寫demo時,遇到了很多局部滾動的坑,在這里分享一下這些坑的解決方案。以下的坑只針對ios。
約定把產生滾動條的元素稱之為視窗
全局滾動:滾動條在body或者body父級元素上。
局部滾動:滾動條在body里的子孫元素上。
局部滾動優勢每個局部滾動擁有自己的滾動條,這是全局滾動所不能取代的。最典型的是列子如局部滾動,全局滾動。不難發現全局滾動不同的tab之間共享一個滾動條,也就是說其中一個tab滾動了,另一個tab也會跟著滾動。
可以解決input fixed定位失效問題。
全局滾動有出界情況,出界就是滑到最頂端和最底端后繼續滑。這樣會出現一個很惡心的效果。局部滾動雖然也會有這個情況,但是能修復,全局滾動至少我不會修。
坑(一)ios瀏覽器局部滾動默認沒有彈性滾動的效果。解決方法是為body或者視窗加-webkit-overflow-scrolling: touch。其實加這兩個地方都一樣,雖然在文檔中并沒有說該屬性有繼承性的,不過我在safari下測試出來是有繼承性的。該屬性具體說明看這里。
坑(二)先看一下視頻效果:沒用ScrollFix
ios局部滾動的出界情況,當你的滾動條在最頂端的時候,你會發現此時你的列表不再滾動而是產生全局滾動了。其實這個確實應該是這樣的。如果此時你的視窗占了比整個window還要大,就會一直在視窗里滾動,你還讓不讓用戶看其他內容了。但視窗的滾動條在最頂端的時候的時候下滑又迅速上滑你會發現還是在做全局滾動。這個也應該是這樣的,全局滾動還沒停下來不可能做局部滾動吧。同理當你滾動條在最下面的時候也會出現這樣的狀況。但有時候,你就不會想以上的效果。
其實解決方案很簡單,既然知道了問題是滾動條在最頂端和最底端的時候才會出現的,那么你只要在touchstart的時候判斷scrollTop是否為這兩個值,如果是就加1或者減1。這里有一個別人已經實現的庫ScrollFix。視頻效果:用了ScrollFix。貼一下核心代碼
var ScrollFix = function(elem) { var startY, startTopScroll; elem.addEventListener("touchstart", function(event){ startY = event.touches[0].pageY; startTopScroll = elem.scrollTop; //當滾動條在最頂部的時候 if(startTopScroll <= 0) elem.scrollTop = 1; //當滾動條在最底部的時候 if(startTopScroll + elem.offsetHeight >= elem.scrollHeight) elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1; }, false); };
但是這個庫一定要謹慎用。因為他監聽了touchstart事件,這個事件會使滾動滯后(在這里并不明顯),passive event listeners。當然你不能用文章里的解決方法,否則如果你快速滑動,由于touchstart事件的監聽函數還沒執行到就已經開始滾動了所以可能還是會發生上面的情況,ScrollFix這個庫就無效了。
坑(三)還是先看一下視頻效果: 有問題的視頻
這個坑就是你的內容不滿視窗一個屏幕的時候,你向上滑動你會發現整個視窗都動了,也就成了全局滾動。這個現象是正常的,內容都不滿一屏當然不需要滾動啊,甚至連滾動條都沒產生。
理由也說了,內容不足一個屏幕產生的現象,那么讓內容時刻保持在一屏之上不就可以了。這里我寫了一個庫,LocalScrollFix。貼一下核心代碼
update() { //當內容超過一屏的時候isArrived為true if (this.isArrived) { return } //每次調用update方法時候都去更新fixDom的paddingTop值 const fixDomPaddingTop = this.computerFixDomPaddingTop() if (fixDomPaddingTop >= 0) { //只有當計算后的值大于0才要更新 this.fixDom.style.paddingTop = `${fixDomPaddingTop + 2}px` } else { //當計算后的值小于0的時候,也就是原來的內容就超過一屏幕了。arrived方法中會把fixDom移除。 this.arrived() } } //計算fixDom所需要的paddingTop值 computerFixDomPaddingTop() { //fixDom指的是append到最底部的dom。win指的是視窗 const {fixDom, win} = this //一開始想內容的高度+paddingTop==數創的高度。因為直接求內容的高度其實并不簡單。 //所以稍微變通了以下,讓窗口的top值減去fixDom的top值其實就是fixDom的paddingTop值 //在把視窗的borderBottomWidth和視窗的paddingBottom考慮進去 const fixDomTop = fixDom.getBoundingClientRect().top const winBottom = win.getBoundingClientRect().bottom const {paddingBottom: winPaddingBottom, borderBottomWidth: winBorderBottomWidth}= window.getComputedStyle(win, null) return winBottom - parseFloat(winPaddingBottom) - parseFloat(winBorderBottomWidth) - fixDomTop }
大概就是在視窗內append一個元素,當你調用update方法的時候就去更新這個元素的paddingTop值來使視窗的內容超過一屏。
最佳實踐ios下可以用局部滾動替代全局滾動,安卓用全局滾動(老的安卓手機在局部滾動上貌似有嚴重的性能問題)。可能很多人會擔心這樣比較麻煩,其實仔細思考一下并沒有增加多少代碼。可以參考最佳實踐,源碼。
順便說一下,如果你使用Scrollload來作為滾動到底部加載的插件,那么坑二就只需要把配置useScrollFix設置為true,坑三只需要把配置useLocalScrollFix設置為true。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/81188.html
摘要:原文地址初衷如今移動端站點越來越多,滾動到底部加載數據和下拉刷新的需求非常的常見,即使現在很多站點也會有這樣的需求,比如百度首頁就有。 原文地址 https://github.com/fa-ge/Scrollload/blob/master/README.md 初衷 如今移動端站點越來越多,滾動到底部加載數據和下拉刷新的需求非常的常見,即使現在很多pc站點也會有這樣的需求,比如百度首頁...
摘要:起因及介紹在處理原始對賬文件的時候,我將數據歸類后批量存入相應的表中。結論事務只能管著開啟事務的線程,其他子線程出了問題都感知不到,所以在多線程環境操作要慎重。高頻容易搞死服務器,低頻會阻塞自身程序。重試次數和超時時間根據業務情況設置。 起因及介紹 在處理原始對賬文件的時候,我將數據歸類后批量存入相應的表中。在持久化的時候,用了parallelStream(),想著同時存入很多表這樣可...
摘要:但對于我們的對于界面還原度要求較高,對于之間的間距也有一些要求,所以也要處理,對于間距部分的處理可以按照之前的方式通過反射來完成。注意,這種方式因為需要計算的文字寬度,所以要放到設置完所有的后調用。 修改下劃線寬度的坑 效果如下: showImg(https://s2.ax1x.com/2019/04/18/ES2KYV.png); 代碼實現方式: 如果想要實現這種效果,最主要控制的就...
閱讀 4275·2021-09-26 10:11
閱讀 2674·2021-07-28 00:37
閱讀 3227·2019-08-29 15:29
閱讀 1189·2019-08-29 15:23
閱讀 3130·2019-08-26 18:37
閱讀 2471·2019-08-26 10:37
閱讀 603·2019-08-23 17:04
閱讀 2350·2019-08-23 13:44