成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

ios局部滾動(dòng)的坑及解決方案

yhaolpz / 3258人閱讀

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

起因

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

約定

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

全局滾動(dòng):滾動(dòng)條在body或者body父級(jí)元素上。

局部滾動(dòng):滾動(dòng)條在body里的子孫元素上。

局部滾動(dòng)優(yōu)勢(shì)

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

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

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

坑(一)

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

坑(二)
問題

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

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

解決方案

其實(shí)解決方案很簡(jiǎn)單,既然知道了問題是滾動(dòng)條在最頂端和最底端的時(shí)候才會(huì)出現(xiàn)的,那么你只要在touchstart的時(shí)候判斷scrollTop是否為這兩個(gè)值,如果是就加1或者減1。這里有一個(gè)別人已經(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)滾動(dòng)條在最頂部的時(shí)候
        if(startTopScroll <= 0)
            elem.scrollTop = 1;
        //當(dāng)滾動(dòng)條在最底部的時(shí)候
        if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
            elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
    }, false);
};

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

坑(三)

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

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

解決方案

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

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

最佳實(shí)踐

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

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/81188.html

相關(guān)文章

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

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

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

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

    wums 評(píng)論0 收藏0
  • TabLayout使用遇到坑及方案

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

    baishancloud 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<