【JS】687- 幾行代碼摸清楚上拉加載原理

https://www.cnblogs.com/chanwahfung
效果
貼上效果展示:
實現(xiàn)思路
樣式方面不多贅述,滾動區(qū)域是給固定高度,設(shè)置 overflow-y: auto 來實現(xiàn)。
接下來看看js方面的實現(xiàn),其實也很簡單,觸發(fā)的條件是:可視高度 + 滾動距離 >= 實際高度 。例子我會使用vue來實現(xiàn),和原生實現(xiàn)是一樣的。
可視高度(offsetHeight):通過 dom的offsetHeight獲得,表示區(qū)域固定的高度。這里我推薦通過getBoundingClientRect()來獲取高度,因為使用前者會引起瀏覽器回流,造成一些性能問題。滾動高度(scrollTop):滾動事件中通過 e.target.scrollTop獲取,表示滾動條距離頂部的px實際高度(scrollHeight):通過 dom的scrollHeight獲得,表示區(qū)域內(nèi)所有內(nèi)容的高度(包括滾動距離),也就是實際高度
基礎(chǔ)實現(xiàn)
onScroll(e)?{
????let?scrollTop?=?e.target.scrollTop
????let?scrollHeight?=?e.target.scrollHeight
????let?offsetHeight?=?Math.ceil(e.target.getBoundingClientRect().height)
????let?currentHeight?=?scrollTop?+?offsetHeight
????if?(currentHeight?>=?scrollHeight)?{
????????console.log('觸底')
????}
}

so easy~
加點細節(jié)
加點細節(jié),現(xiàn)在我們希望是離底部一定距離就觸發(fā)事件,而不是等到完全觸底。如果你做過小程序,這和onReachBottom差不多的意思。
聲明一個離底部的距離變量reachBottomDistance
這時候觸發(fā)條件:可視高度 + 滾動距離 + reachBottomDistance >= 實際高度
export?default?{
??data(){
????return?{
??????reachBottomDistance:?100
????}
??},
??methods:?{
????onScroll(e)?{
????????let?scrollTop?=?e.target.scrollTop
????????let?scrollHeight?=?e.target.scrollHeight
????????let?offsetHeight?=?Math.ceil(e.target.getBoundingClientRect().height)
????????let?currentHeight?=?scrollTop?+?offsetHeight?+?this.reachBottomDistance
????????if?(currentHeight?>=?scrollHeight)?{
????????????console.log('觸底')
????????}
????}
??}
}

在距離底部100px時成功觸發(fā)事件,但由于100px往下的區(qū)域是符合條件的,會導(dǎo)致一直觸發(fā),這不是我們想要的。
接下來做一些處理,讓其進入后只觸發(fā)一次:
export?default?{
??data(){
????return?{
??????isReachBottom:?false,
??????reachBottomDistance:?100
????}
??},
??methods:?{
????onScroll(e)?{
????????let?scrollTop?=?e.target.scrollTop
????????let?scrollHeight?=?e.target.scrollHeight
????????let?offsetHeight?=?Math.ceil(e.target.getBoundingClientRect().height)
????????let?currentHeight?=?scrollTop?+?offsetHeight?+?this.reachBottomDistance
????????if(currentHeight???????????this.isReachBottom?=?false
????????}
????????if(this.isReachBottom){
??????????return
????????}
????????if?(currentHeight?>=?scrollHeight)?{
??????????this.isReachBottom?=?true
??????????console.log('觸底')
????????}
????}
??}
}

優(yōu)化
實時去獲取位置信息稍微會損耗性能,我們應(yīng)該把不變的緩存起來,只實時獲取可變的部分
export?default?{
??data(){
????return?{
??????isReachBottom:?false,
??????reachBottomDistance:?100
??????scrollHeight:?0,
??????offsetHeight:?0,
????}
??},
??mounted(){
????//?頁面加載完成后??將高度存儲起來
????let?dom?=?document.querySelector('.comment-area?.comment-list')
????this.scrollHeight?=?dom.scrollHeight
????this.offsetHeight?=?Math.ceil(dom.getBoundingClientRect().height)
??},
??methods:?{
????onScroll(e)?{
????????let?scrollTop?=?e.target.scrollTop
????????let?currentHeight?=?scrollTop?+?this.offsetHeight?+?this.reachBottomDistance
????????if(currentHeight???????????this.isReachBottom?=?false
????????}
????????if(this.isReachBottom){
??????????return
????????}
????????if?(currentHeight?>=?this.scrollHeight)?{
??????????this.isReachBottom?=?true
??????????console.log('觸底')
????????}
????}
??}
}
實現(xiàn)到這里就告一段落,如果你有更好的思路和值得改進的地方,歡迎交流~

回復(fù)“加群”與大佬們一起交流學(xué)習(xí)~
點擊“閱讀原文”查看70+篇原創(chuàng)文章

評論
圖片
表情
