成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

ios局部滾動的坑及解決方案

yhaolpz / 3189人閱讀

摘要:起因最近幾天在寫一個滾動加載更多數(shù)據(jù)的插件,為局部滾動寫時,遇到了很多局部滾動的坑,在這里分享一下這些坑的解決方案。約定把產(chǎn)生滾動條的元素稱之為視窗全局滾動滾動條在或者父級元素上??右粸g覽器局部滾動默認(rèn)沒有彈性滾動的效果。

起因

最近幾天在寫一個滾動加載更多數(shù)據(jù)的插件(Scrollload),為局部滾動寫demo時,遇到了很多局部滾動的坑,在這里分享一下這些坑的解決方案。以下的坑只針對ios。

約定

把產(chǎn)生滾動條的元素稱之為視窗

全局滾動:滾動條在body或者body父級元素上。

局部滾動:滾動條在body里的子孫元素上。

局部滾動優(yōu)勢

每個局部滾動擁有自己的滾動條,這是全局滾動所不能取代的。最典型的是列子如局部滾動,全局滾動。不難發(fā)現(xiàn)全局滾動不同的tab之間共享一個滾動條,也就是說其中一個tab滾動了,另一個tab也會跟著滾動。

可以解決input fixed定位失效問題。

全局滾動有出界情況,出界就是滑到最頂端和最底端后繼續(xù)滑。這樣會出現(xiàn)一個很惡心的效果。局部滾動雖然也會有這個情況,但是能修復(fù),全局滾動至少我不會修。

坑(一)

ios瀏覽器局部滾動默認(rèn)沒有彈性滾動的效果。解決方法是為body或者視窗加-webkit-overflow-scrolling: touch。其實(shí)加這兩個地方都一樣,雖然在文檔中并沒有說該屬性有繼承性的,不過我在safari下測試出來是有繼承性的。該屬性具體說明看這里。

坑(二)
問題

先看一下視頻效果:沒用ScrollFix

ios局部滾動的出界情況,當(dāng)你的滾動條在最頂端的時候,你會發(fā)現(xiàn)此時你的列表不再滾動而是產(chǎn)生全局滾動了。其實(shí)這個確實(shí)應(yīng)該是這樣的。如果此時你的視窗占了比整個window還要大,就會一直在視窗里滾動,你還讓不讓用戶看其他內(nèi)容了。但視窗的滾動條在最頂端的時候的時候下滑又迅速上滑你會發(fā)現(xiàn)還是在做全局滾動。這個也應(yīng)該是這樣的,全局滾動還沒停下來不可能做局部滾動吧。同理當(dāng)你滾動條在最下面的時候也會出現(xiàn)這樣的狀況。但有時候,你就不會想以上的效果。

解決方案

其實(shí)解決方案很簡單,既然知道了問題是滾動條在最頂端和最底端的時候才會出現(xiàn)的,那么你只要在touchstart的時候判斷scrollTop是否為這兩個值,如果是就加1或者減1。這里有一個別人已經(jīng)實(shí)現(xiàn)的庫ScrollFix。視頻效果:用了ScrollFix。貼一下核心代碼

var ScrollFix = function(elem) {
    var startY, startTopScroll;
    elem.addEventListener("touchstart", function(event){
        startY = event.touches[0].pageY;
        startTopScroll = elem.scrollTop;
        //當(dāng)滾動條在最頂部的時候
        if(startTopScroll <= 0)
            elem.scrollTop = 1;
        //當(dāng)滾動條在最底部的時候
        if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
            elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
    }, false);
};

但是這個庫一定要謹(jǐn)慎用。因為他監(jiān)聽了touchstart事件,這個事件會使?jié)L動滯后(在這里并不明顯),passive event listeners。當(dāng)然你不能用文章里的解決方法,否則如果你快速滑動,由于touchstart事件的監(jiān)聽函數(shù)還沒執(zhí)行到就已經(jīng)開始滾動了所以可能還是會發(fā)生上面的情況,ScrollFix這個庫就無效了。

坑(三)

還是先看一下視頻效果: 有問題的視頻

這個坑就是你的內(nèi)容不滿視窗一個屏幕的時候,你向上滑動你會發(fā)現(xiàn)整個視窗都動了,也就成了全局滾動。這個現(xiàn)象是正常的,內(nèi)容都不滿一屏當(dāng)然不需要滾動啊,甚至連滾動條都沒產(chǎn)生。

解決方案

理由也說了,內(nèi)容不足一個屏幕產(chǎn)生的現(xiàn)象,那么讓內(nèi)容時刻保持在一屏之上不就可以了。這里我寫了一個庫,LocalScrollFix。貼一下核心代碼

    update() {
      //當(dāng)內(nèi)容超過一屏的時候isArrived為true
        if (this.isArrived) {
            return
        }
      //每次調(diào)用update方法時候都去更新fixDom的paddingTop值
        const fixDomPaddingTop = this.computerFixDomPaddingTop()
        
        if (fixDomPaddingTop >= 0) {
              //只有當(dāng)計算后的值大于0才要更新
            this.fixDom.style.paddingTop = `${fixDomPaddingTop + 2}px`
        } else {
          //當(dāng)計算后的值小于0的時候,也就是原來的內(nèi)容就超過一屏幕了。arrived方法中會把fixDom移除。
            this.arrived()
        }
    }
    //計算fixDom所需要的paddingTop值
    computerFixDomPaddingTop() {
          //fixDom指的是append到最底部的dom。win指的是視窗
        const {fixDom, win} = this
        //一開始想內(nèi)容的高度+paddingTop==數(shù)創(chuàng)的高度。因為直接求內(nèi)容的高度其實(shí)并不簡單。
        //所以稍微變通了以下,讓窗口的top值減去fixDom的top值其實(shí)就是fixDom的paddingTop值
        //在把視窗的borderBottomWidth和視窗的paddingBottom考慮進(jìn)去
        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
    }

大概就是在視窗內(nèi)append一個元素,當(dāng)你調(diào)用update方法的時候就去更新這個元素的paddingTop值來使視窗的內(nèi)容超過一屏。

最佳實(shí)踐

ios下可以用局部滾動替代全局滾動,安卓用全局滾動(老的安卓手機(jī)在局部滾動上貌似有嚴(yán)重的性能問題)。可能很多人會擔(dān)心這樣比較麻煩,其實(shí)仔細(xì)思考一下并沒有增加多少代碼??梢詤⒖甲罴褜?shí)踐,源碼。

順便說一下,如果你使用Scrollload來作為滾動到底部加載的插件,那么坑二就只需要把配置useScrollFix設(shè)置為true,坑三只需要把配置useLocalScrollFix設(shè)置為true。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81188.html

相關(guān)文章

  • 原生js滾動到底部加載數(shù)據(jù)和下拉刷新 Scrollload

    摘要:原文地址初衷如今移動端站點(diǎn)越來越多,滾動到底部加載數(shù)據(jù)和下拉刷新的需求非常的常見,即使現(xiàn)在很多站點(diǎn)也會有這樣的需求,比如百度首頁就有。 原文地址 https://github.com/fa-ge/Scrollload/blob/master/README.md 初衷 如今移動端站點(diǎn)越來越多,滾動到底部加載數(shù)據(jù)和下拉刷新的需求非常的常見,即使現(xiàn)在很多pc站點(diǎn)也會有這樣的需求,比如百度首頁...

    HollisChuang 評論0 收藏0
  • 事務(wù)與多線程坑及調(diào)優(yōu)Tips

    摘要:起因及介紹在處理原始對賬文件的時候,我將數(shù)據(jù)歸類后批量存入相應(yīng)的表中。結(jié)論事務(wù)只能管著開啟事務(wù)的線程,其他子線程出了問題都感知不到,所以在多線程環(huán)境操作要慎重。高頻容易搞死服務(wù)器,低頻會阻塞自身程序。重試次數(shù)和超時時間根據(jù)業(yè)務(wù)情況設(shè)置。 起因及介紹 在處理原始對賬文件的時候,我將數(shù)據(jù)歸類后批量存入相應(yīng)的表中。在持久化的時候,用了parallelStream(),想著同時存入很多表這樣可...

    wums 評論0 收藏0
  • TabLayout使用遇到坑及方案

    摘要:但對于我們的對于界面還原度要求較高,對于之間的間距也有一些要求,所以也要處理,對于間距部分的處理可以按照之前的方式通過反射來完成。注意,這種方式因為需要計算的文字寬度,所以要放到設(shè)置完所有的后調(diào)用。 修改下劃線寬度的坑 效果如下: showImg(https://s2.ax1x.com/2019/04/18/ES2KYV.png); 代碼實(shí)現(xiàn)方式: 如果想要實(shí)現(xiàn)這種效果,最主要控制的就...

    baishancloud 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<