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

資訊專欄INFORMATION COLUMN

如何實現(xiàn)無限滾動

antz / 2182人閱讀

摘要:簡介無限滾動對我們來說已經(jīng)是很常見的功能了,具體表現(xiàn)為當(dāng)頁面滾動到某個位置時就自動加載數(shù)據(jù),本文將探討無限滾動的實現(xiàn)原理以及優(yōu)化。

簡介

無限滾動對我們來說已經(jīng)是很常見的功能了,具體表現(xiàn)為當(dāng)頁面滾動到某個位置時就自動加載數(shù)據(jù),本文將探討無限滾動的實現(xiàn)原理以及優(yōu)化。

原理

我們先看看最簡單的無限滾動的例子:

function fetchData() {
  fetch(path).then(res => doSomeThing(res.data));
}

window.addEventListener("scroll", fetchData);

上面就是無限滾動最簡單的例子啦~
其實就是監(jiān)聽 window 對象的 scroll 事件,然后再觸發(fā)獲取數(shù)據(jù)的函數(shù)~

然而,上面的例子中還有很多問題,其中最大的問題就是 獲取數(shù)據(jù)的函數(shù)(以后叫 fetch 函數(shù))沒有觸發(fā)條件, 我們還需要不斷優(yōu)化,才能在生產(chǎn)環(huán)境下使用。

添加觸發(fā)條件

我們先想想,一般情況下,fetch 函數(shù)的觸發(fā)條件有哪些呢 ?

在 fetch 過程中不能重復(fù)觸發(fā)

沒有更多數(shù)據(jù)的時候不能再觸發(fā)

屏幕距離容器邊緣 xxx 的時候觸發(fā)

前兩點(diǎn)很好處理,只要加個 isLoadingisEnd 的變量就可以了。
添加這兩個變量之后,我們的代碼就變成下面的樣子啦:

var isLoading = false;
var isEnd = false;

function fetchData() {

  if ( !isLoading && !isEnd ) {

    isLoading = true;

    fetch(path).then(res => {
      isLoading = false;
      res.data.length === 0 && isEnd = true;
      doSomething(res.data);
    });

  }

}
window.addEventListener("scroll", fetchData);

第三點(diǎn)對不熟悉 DOM 的童鞋來說就有點(diǎn)難度了~

計算屏幕與容器邊緣的距離

我們以計算屏幕底部與容器底部邊緣為例:

如果有 api 可以直接得到元素底部與屏幕底部的距離就最好啦,可以省去麻煩,但實際上并沒有這樣的 api。
然而,我們可以通過瀏覽器提供的兩個 api,計算出元素底部與屏幕底部之間的距離。

第一個 api 是 window.innerHeight,它返回的是屏幕(viewport)高度。
第二個 api 就是 Element.getBoundingClientRect ,這個方法用來計算元素邊緣與屏幕(viewport)之間的距離。
需要提醒一下,Element.getBoundingClientRect 會得到這么一個類 Object 對象:

ClientRect {
  width: 760,   // 元素寬度
  height: 2500, // 元素高度
  top: -1352,   // 元素上邊緣與屏幕上邊緣的距離
  bottom: 1239, // 元素下邊緣與屏幕上邊緣的距離
  left: 760,    // 元素左邊緣與屏幕左邊緣的距離
  right: 860    // 元素右邊緣與屏幕左邊緣的距離
}

可以看看下面這圖:

     +------> +--------------------------------------------------------+
     |        |                     document.body                      |
     |        |                                                        |
     |        |                                                        |
body.getBoundingClientRect().top                                       |
     |        |                                                        |
     |        |                                                        |
     |        +--------------------------------------------------------+
     |        | browser                                              x |
     +------> +--------------------------------------------------------+ <--+
     |        | window                                                 |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
window.innerHeight                                                     |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                               body.getBoundingClientRect().bottom
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     +------> +--------------------------------------------------------+    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              +--------------------------------------------------------+ <--+



有了這兩個 api,我們很容易就可以計算出元素底部邊緣與屏幕底部邊緣的位置啦~

我們再修改下我們的代碼:

var isLoading = false;
var isEnd = false;
var triggerDistance = 200;

function fetchData() {

  var distance = container.getBoundingClientRect().bottom - window.innerHeight;
  if ( !isLoading && !isEnd && distance < triggerDistance ) {

    isLoading = true;

    fetch(path).then(res => {
      isLoading = false;
      res.data.length === 0 && isEnd = true;
      doSomething(res.data);
    });

  }

}
window.addEventListener("scroll", fetchData);

修改之后,當(dāng)容器底部與屏幕底部距離小于 200 的時候,才會觸發(fā) fetch 函數(shù),這樣我們的無限滾動就更加實用啦!

支持 window 以外的元素

然而,并不是只有 window 才可以滾動,擁有高度的級塊元素只要設(shè)置了 overflow: scroll 都是可以滾動的。
我們需要再修改一下代碼來讓級塊元素也支持無限滾動!

function fetchData() { /* do something */ }
window.addEventListener("scroll", fetchData);
document.getElementById("container").addEventListener("scroll", fetchData);

很簡單吧!只需要為該容器元素添加一個 scroll 的事件監(jiān)聽器就好啦!

出處

http://scarletsky.github.io/2016/04/20/how-to-implement-infinite-scroll/

參考資料

https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

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

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

相關(guān)文章

  • Vue下滾動到頁面底部無限加載數(shù)據(jù)Demo

    摘要:下滾動到頁面底部無限加載數(shù)據(jù)看到一篇覺得挺實用的就看了下順便簡單翻譯了一下給需要的人參考從這個項目中可以加深對的生命周期的理解何時開始請求如何結(jié)合使用原生來寫事件等等我這里主要是對原文的重點(diǎn)提取和補(bǔ)充本文技術(shù)要點(diǎn)生命周期簡單用法格式化日期圖 Vue下滾動到頁面底部無限加載數(shù)據(jù)Demo 看到一篇Implementing an Infinite Scroll with Vue.js, 覺得...

    elarity 評論0 收藏0
  • 在React項目中,如何優(yōu)雅的優(yōu)化長列表

    摘要:合理的優(yōu)化長列表,可以提升用戶體驗。這樣保證了無論如何滾動,真實渲染出的節(jié)點(diǎn)只有可視區(qū)內(nèi)的列表元素。具體效果如下圖所示對于比無優(yōu)化的情況,優(yōu)化后的虛擬列表渲染速度提升很明顯。是基于來實現(xiàn)的,但是是一個維的列表,而不是網(wǎng)狀。 ??對于較長的列表,比如1000個數(shù)組的數(shù)據(jù)結(jié)構(gòu),如果想要同時渲染這1000個數(shù)據(jù),生成相應(yīng)的1000個原生dom,我們知道原生的dom元素是很復(fù)雜的,如果長列表...

    yearsj 評論0 收藏0
  • 在React項目中,如何優(yōu)雅的優(yōu)化長列表

    摘要:合理的優(yōu)化長列表,可以提升用戶體驗。這樣保證了無論如何滾動,真實渲染出的節(jié)點(diǎn)只有可視區(qū)內(nèi)的列表元素。具體效果如下圖所示對于比無優(yōu)化的情況,優(yōu)化后的虛擬列表渲染速度提升很明顯。是基于來實現(xiàn)的,但是是一個維的列表,而不是網(wǎng)狀。 ??對于較長的列表,比如1000個數(shù)組的數(shù)據(jù)結(jié)構(gòu),如果想要同時渲染這1000個數(shù)據(jù),生成相應(yīng)的1000個原生dom,我們知道原生的dom元素是很復(fù)雜的,如果長列表...

    Java_oldboy 評論0 收藏0
  • 【譯】無限滾動加載最佳實踐

    摘要:優(yōu)秀無限滾動的五項原則將無限滾動做好,并不是不可能完成的任務(wù)。提供為特定項添加書簽的可能無限滾動最常見的缺點(diǎn)之一就是,內(nèi)容出現(xiàn)的時候,沒法添加書簽。結(jié)論無限滾動實現(xiàn)得好的話,可以達(dá)到令人難以置信的光滑無縫體驗。 本文轉(zhuǎn)載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/673原文:https://uxplanet.org/infinite-scrolli...

    Sunxb 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<