如何实现无限滚动
簡介
無限滾動對我們來說已經(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ā)
前兩點很好處理,只要加個 isLoading 和 isEnd 的變量就可以了。
添加這兩個變量之后,我們的代碼就變成下面的樣子啦:
第三點對不熟悉 DOM 的童鞋來說就有點難度了~
計算屏幕與容器邊緣的距離
我們以計算屏幕底部與容器底部邊緣為例:
如果有 api 可以直接得到元素底部與屏幕底部的距離就最好啦,可以省去麻煩,但實際上并沒有這樣的 api。
然而,我們可以通過瀏覽器提供的兩個 api,計算出元素底部與屏幕底部之間的距離。
第一個 api 是 window.innerHeight,它返回的是屏幕(viewport)高度。
第二個 api 就是 Element.getBoundingClientRect ,這個方法用來計算元素邊緣與屏幕(viewport)之間的距離。
需要提醒一下,Element.getBoundingClientRect 會得到這么一個類 Object 對象:
可以看看下面這圖:
+------> +--------------------------------------------------------+| | 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 都是可以滾動的。
我們需要再修改一下代碼來讓級塊元素也支持無限滾動!
很簡單吧!只需要為該容器元素添加一個 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
總結(jié)
- 上一篇: iOS开发者有价值的工具集
- 下一篇: 导出websphere内存镜像