亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

如何實(shí)現(xiàn)無限滾動(dòng)

antz / 2244人閱讀

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

簡介

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

原理

我們先看看最簡單的無限滾動(dòng)的例子:

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

window.addEventListener("scroll", fetchData);

上面就是無限滾動(dòng)最簡單的例子啦~
其實(shí)就是監(jiān)聽 window 對(duì)象的 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ù)的時(shí)候不能再觸發(fā)

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

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

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)對(duì)不熟悉 DOM 的童鞋來說就有點(diǎn)難度了~

計(jì)算屏幕與容器邊緣的距離

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

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

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

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
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     +------> +--------------------------------------------------------+    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              +--------------------------------------------------------+ <--+



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

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

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 的時(shí)候,才會(huì)觸發(fā) fetch 函數(shù),這樣我們的無限滾動(dòng)就更加實(shí)用啦!

支持 window 以外的元素

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

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

很簡單吧!只需要為該容器元素添加一個(gè) 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)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/79231.html

相關(guān)文章

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

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

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

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

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

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

    Java_oldboy 評(píng)論0 收藏0
  • 【譯】無限滾動(dòng)加載最佳實(shí)踐

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

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

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

0條評(píng)論

閱讀需要支付1元查看
<