摘要:實(shí)現(xiàn)列表動(dòng)態(tài)無限滾動(dòng)問題在開發(fā)頁面工程中,經(jīng)常會(huì)遇到滾動(dòng)列表當(dāng)實(shí)際需要顯示的內(nèi)容寬度或高度超過容器的寬度或高度時(shí),設(shè)置當(dāng)滾動(dòng)列表中的內(nèi)容比較少時(shí),我們可以一次性加載所有的內(nèi)容到列表容器中顯示。
JS+HTML實(shí)現(xiàn)列表動(dòng)態(tài)無限滾動(dòng) 問題
在HTML開發(fā)頁面工程中,經(jīng)常會(huì)遇到滾動(dòng)列表-當(dāng)實(shí)際需要顯示的內(nèi)容寬度或高度超過容器的寬度或高度時(shí),設(shè)置CSS
overflow-x:auto; overfow-y:auto;
當(dāng)滾動(dòng)列表中的內(nèi)容比較少時(shí),我們可以一次性加載所有的內(nèi)容到列表容器中顯示。
當(dāng)滾動(dòng)列表中的內(nèi)容比較多,使用分頁加載的方式逐步加載數(shù)據(jù),2種方式
1.通過在列表的末尾添加一個(gè)標(biāo)別元素indicator,和添加列表的scroll事件來監(jiān)聽indicator元素是否可見,如果可見那么提交請(qǐng)求加載下一頁數(shù)據(jù),append到列表內(nèi)容的尾部。通過這個(gè)方式可以實(shí)現(xiàn)數(shù)據(jù)的無限加載,一直到數(shù)據(jù)取完。
2.在列表下部添加分頁工具條,用戶通過請(qǐng)求獲取指定頁的數(shù)據(jù)并且替換到當(dāng)前列表里的內(nèi)容
對(duì)于方式1對(duì)用戶想對(duì)友好,加載過的數(shù)據(jù)不會(huì)重復(fù)加載,請(qǐng)求的資源少,但是當(dāng)量多時(shí),頁面上的DOM元素量很不斷增加,消耗的內(nèi)存也會(huì)加大
方式2用戶每翻一頁都要重新請(qǐng)求數(shù)據(jù),即使對(duì)于翻過看過的數(shù)據(jù)想要重新看也是如此,請(qǐng)求資源多,好處是頁面DOM元素?cái)?shù)量固定,占用內(nèi)存資源少
那么有沒有一種方式結(jié)合方式1和方式2的優(yōu)點(diǎn),摒棄缺點(diǎn),融合優(yōu)化下呢?
~~有!有方法~~解決方案:
對(duì)當(dāng)前列表的寬高固定,對(duì)列表包含的內(nèi)容高度固定,列表滾動(dòng)滿足條件時(shí)動(dòng)態(tài)刪除或添加元素,保持元素?cái)?shù)量的固定已經(jīng)內(nèi)容在列表可視區(qū)域的正確顯示。
列表能夠無限滾動(dòng),數(shù)據(jù)能夠無限加載,DOM元素保持一定數(shù)量
先放出實(shí)現(xiàn)的代碼吧
HTML部分Title 123456789101112131415161718192021222324252627282930
.infinity-scroll指定列表容器,CSS設(shè)置其水平不滾動(dòng),垂直方向自動(dòng)滾動(dòng)
.main-content為滾動(dòng)內(nèi)容組件,其高度隨著實(shí)際內(nèi)容的增多而加大
.item為滾動(dòng)內(nèi)容的單個(gè)項(xiàng)目元素
.first-item為當(dāng)前放置在列表容器內(nèi)的內(nèi)容的第1個(gè)元素,同時(shí)為當(dāng)前滾動(dòng)到頂部的標(biāo)識(shí)元素
.last-item為當(dāng)前放置在列表容器內(nèi)的內(nèi)容的最后一個(gè)元素,同時(shí)為當(dāng)前滾動(dòng)到底部的標(biāo)識(shí)元素
放3組元素作為初始的列表內(nèi)容,為什么是3組呢?為了保證滾動(dòng)的流暢性,當(dāng)前列表窗口顯示一組,卷起一組,下部隱藏一組
JS部分$(".infinity-scroll").on("scroll",infinity_scrollFun);
為列表添加scroll事件監(jiān)聽infinity_scrollFun
infinity_scrollFun函數(shù)
計(jì)算列表容器的高度和離viewpoint頂部距離
if(!infinity_scroll_height){ infinity_scroll_height=$(".infinity-scroll")[0].getBoundingClientRect().height; infinity_scroll_top=$(".infinity-scroll")[0].getBoundingClientRect().top; }
計(jì)算.last-item的位置,如果正在加載數(shù)據(jù)不執(zhí)行任何動(dòng)作
if(isLoading){ return; }else{ last_item_top=$(".item.last-item")[0].getBoundingClientRect().top; last_item_top=last_item_top-infinity_scroll_top; }
如果.last-item出現(xiàn)在列表窗口,那么加載新的數(shù)據(jù)
if(last_item_top<=infinity_scroll_height){ isLoading=true; appendNewItems($(".main-content")[0].getBoundingClientRect().height,$(this).scrollTop()); return; }
如果.first-item出現(xiàn)在列表窗口,那么restore原來已經(jīng)加載過的數(shù)據(jù)
first_item_top=$(".item.first-item")[0].getBoundingClientRect().top; first_item_top=first_item_top-infinity_scroll_top; console.log("~~first_item_top~~~%s",first_item_top); if(first_item_top>=0){ restorePreItems($(".main-content")[0].getBoundingClientRect().height,$(this).scrollTop()); return; }
appendNewItems函數(shù)
保持總體元素的個(gè)數(shù),將.first-item后的10個(gè)元素刪除,添加新的內(nèi)容到底部,并要保持內(nèi)容的實(shí)際高度及顯示在列表窗口的內(nèi)容的位置
$(".item").slice(0,10).remove(); $(".item").first().addClass("first-item"); var mainContentPaddingTop=$(".main-content").css("padding-top"); mainContentPaddingTop=parseFloat(mainContentPaddingTop.split("px")[0]||0); $(".main-content").append(documentFragment); if(lastMaxItemIndexrestorePreItems函數(shù)
功能和appendNewItems函數(shù)類似,只是刪除底部的10個(gè)元素,添加10個(gè)元素到頭部,并要保持內(nèi)容的實(shí)際高度及顯示在列表窗口的內(nèi)容的位置//刪除尾部的10個(gè)元素 $(".item.last-item").prevAll().slice(0,9).remove(); $(".item.last-item").remove(); $(".item").last().addClass("last-item"); mainContentPaddingTop=$(".main-content").css("padding-top"); mainContentPaddingTop=parseFloat(mainContentPaddingTop.split("px")[0]||0); $(".main-content").css({ "padding-top":mainContentPaddingTop-10*50 }); $(".main-content").prepend(documentFragment); $(".infinity-scroll").off("scroll",infinity_scrollFun); $(".infinity-scroll").scrollTop(scroll_top); $(".infinity-scroll").on("scroll",infinity_scrollFun);待改進(jìn)的地方上面的假設(shè)內(nèi)容區(qū)的item的高度都是相同,并且每次加在的item數(shù)量都是相同的。如果內(nèi)容item的高度是動(dòng)態(tài)變化的;
同時(shí)沒有做到頁面DOM元素的復(fù)用,其實(shí)完全可以復(fù)用刪除的元素作為將要添加的元素,只是變更其中的數(shù)據(jù)顯示內(nèi)容;代碼需要做相應(yīng)的修改,就留給小伙伴們改進(jìn)吧:)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/82068.html
摘要:實(shí)現(xiàn)列表動(dòng)態(tài)無限滾動(dòng)問題在開發(fā)頁面工程中,經(jīng)常會(huì)遇到滾動(dòng)列表當(dāng)實(shí)際需要顯示的內(nèi)容寬度或高度超過容器的寬度或高度時(shí),設(shè)置當(dāng)滾動(dòng)列表中的內(nèi)容比較少時(shí),我們可以一次性加載所有的內(nèi)容到列表容器中顯示。 JS+HTML實(shí)現(xiàn)列表動(dòng)態(tài)無限滾動(dòng) 問題 在HTML開發(fā)頁面工程中,經(jīng)常會(huì)遇到滾動(dòng)列表-當(dāng)實(shí)際需要顯示的內(nèi)容寬度或高度超過容器的寬度或高度時(shí),設(shè)置CSS overflow-x:auto;...
摘要:虛擬列表的實(shí)現(xiàn)有多種方案,本文以組件為基礎(chǔ)進(jìn)行分析。常見的無限滾動(dòng)便是延遲渲染的一種實(shí)現(xiàn),而虛擬列表則是按需渲染的一種實(shí)現(xiàn)。接下來,本文會(huì)簡(jiǎn)單介紹虛擬列表的一種實(shí)現(xiàn)方案。實(shí)現(xiàn)本章節(jié)將會(huì)創(chuàng)建一個(gè)組件,并結(jié)合代碼,慢慢梳理虛擬列表的實(shí)現(xiàn)。 在 列表數(shù)據(jù)的展示優(yōu)化 一文中,提到了對(duì)于列表形態(tài)的數(shù)據(jù)展示的按需渲染。這種方式是指根據(jù)容器元素的高度以及列表項(xiàng)元素的高度來顯示長(zhǎng)列表數(shù)據(jù)中的某一個(gè)部分...
摘要:合理的優(yōu)化長(zhǎng)列表,可以提升用戶體驗(yàn)。這樣保證了無論如何滾動(dòng),真實(shí)渲染出的節(jié)點(diǎn)只有可視區(qū)內(nèi)的列表元素。具體效果如下圖所示對(duì)于比無優(yōu)化的情況,優(yōu)化后的虛擬列表渲染速度提升很明顯。是基于來實(shí)現(xiàn)的,但是是一個(gè)維的列表,而不是網(wǎng)狀。 ??對(duì)于較長(zhǎng)的列表,比如1000個(gè)數(shù)組的數(shù)據(jù)結(jié)構(gòu),如果想要同時(shí)渲染這1000個(gè)數(shù)據(jù),生成相應(yīng)的1000個(gè)原生dom,我們知道原生的dom元素是很復(fù)雜的,如果長(zhǎng)列表...
摘要:合理的優(yōu)化長(zhǎng)列表,可以提升用戶體驗(yàn)。這樣保證了無論如何滾動(dòng),真實(shí)渲染出的節(jié)點(diǎn)只有可視區(qū)內(nèi)的列表元素。具體效果如下圖所示對(duì)于比無優(yōu)化的情況,優(yōu)化后的虛擬列表渲染速度提升很明顯。是基于來實(shí)現(xiàn)的,但是是一個(gè)維的列表,而不是網(wǎng)狀。 ??對(duì)于較長(zhǎng)的列表,比如1000個(gè)數(shù)組的數(shù)據(jù)結(jié)構(gòu),如果想要同時(shí)渲染這1000個(gè)數(shù)據(jù),生成相應(yīng)的1000個(gè)原生dom,我們知道原生的dom元素是很復(fù)雜的,如果長(zhǎng)列表...
閱讀 3881·2021-11-24 11:14
閱讀 3321·2021-11-22 13:53
閱讀 3883·2021-11-11 16:54
閱讀 1546·2021-10-13 09:49
閱讀 1211·2021-10-08 10:05
閱讀 3392·2021-09-22 15:57
閱讀 1754·2021-08-16 11:01
閱讀 965·2019-08-30 15:55