JS異步觀察目標(biāo)元素方式完成分頁加載
介紹
平時我們處理分頁加載時,往往是通過滾動條判斷是否到了容器底部再執(zhí)行的加載任務(wù)的,這樣有一個問題就是,不管滾動條是否劃到底部位置,它都會運(yùn)行計算這個函數(shù)。
那么,如果能判斷底部的加載區(qū)域出現(xiàn)后再去執(zhí)行加載,不用再做滾動條計算了,這樣豈不美哉。本期將以異步觀察目標(biāo)元素的新方式去完成分頁加載業(yè)務(wù)。
代碼
<div id="app" @vue:mounted="mounted" :class="{'active':active}">
<ul>
<li v-for="item in num"><span>{{item}}</span>
<p></p>
</li>'
<div class="loading">
<div ref="loading" v-show="!isLoading"></div>
loading..
</div>
</ul>
</div>
#app{
display: none;
&.active{
display: block;
}
}
ul{
width: 100%;
li{
width: 100%;
height: 10vh;
display: flex;
align-items: center;
justify-content: start;
box-sizing: border-box;
padding: 0 3%;
position: relative;
border-bottom: 1px solid #efefef;
font-size: 14px;
font-family: fantasy, Courier, monospace;
span{
display: inline-block;
min-width: 30px;
text-align: center;
}
p{
flex: 1;
height: 4vh;
background-color: #e2e2e2;
margin-left: 3%;
}
}
}
.loading{
font-family: fantasy, Courier, monospace;
display: flex;
height: 15vh;
align-items: center;
justify-content: center;
animation: loading 1s linear infinite;
}
@keyframes loading{
0%,100%{
opacity: 1;
}
50%{
opacity:0;
}
}
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
num: 0,
page:1,
active:false,
observer:null,
isLoading:false,
mounted() {
this.active = true;
this.loading = this.$refs.loading;
this.observer= new IntersectionObserver(()=>{
this.addNum();
},{
root:window.document,
rootMargin:"0px 0px 0px 0px",
threshold:0
})
this.observer.observe(this.loading)
// this.observer.unobserve(this.loading)
},
addNum(){
if(this.isLoading) return;
this.isLoading = true;
console.log(`loading,page:${this.page}`)
setTimeout(()=>{
this.num += 20;
this.page ++;
this.$nextTick(()=>{
this.isLoading = false;
})
},1000)
}
}).mount()
演示

正文
監(jiān)聽元素
IntersectionObserver() 對不少小伙伴來說可能是一個比較生疏的構(gòu)造器,你可以傳入監(jiān)聽區(qū)域,以及監(jiān)聽后的回調(diào)函數(shù),然后它會創(chuàng)建并返回一個 IntersectionObserver 對象,而這個對象可以來完成監(jiān)聽某個目標(biāo)元素是否與該監(jiān)聽區(qū)域發(fā)生交叉,每次達(dá)到檢查閾值后都會觸發(fā)剛才傳入的回調(diào)函數(shù)。
// 獲取監(jiān)聽目標(biāo)
this.loading = this.$refs.loading;
// 用構(gòu)造器創(chuàng)建監(jiān)聽區(qū)域?qū)ο?
this.observer= new IntersectionObserver(()=>{
this.addNum();
},{
root:window.document, // 監(jiān)聽區(qū)域,默認(rèn)為整個可視窗體
rootMargin:"0px 0px 0px 0px", // 類似margin,為邊界的偏移量用于判定范圍是否滿足計算需要,默認(rèn)0px 0px 0px 0px
threshold:0 // 閾值(0-1),表示交叉區(qū)域的比例值,默認(rèn)為0
})
//
this.observer.observe(this.loading)
根據(jù)以上代碼就可以在業(yè)務(wù)中,判斷元素是否出現(xiàn)在,只要達(dá)到閾值就會觸發(fā)回調(diào),在這個回調(diào)函數(shù)中你可以去完成加載列表等操作,從而代替頻繁用計算滾動條的位置距離的困擾。
反復(fù)交叉
或許你在嘗試使用異步觀察目標(biāo)元素的這個寫法時,會發(fā)現(xiàn)一個嚴(yán)重的問題,就是可能本想加載一次的任務(wù)突然出現(xiàn)兩次請求。這又是為什么呢?
其實(shí)就是因為 threshold 這個閾值,表示著交叉區(qū)域的比例值的,當(dāng)你進(jìn)入這個觀察區(qū)域的時候會觸發(fā),當(dāng)頁面內(nèi)容往下填充,會把監(jiān)聽目標(biāo)元素往下推,又到達(dá)了這個閾值從而又觸發(fā)了一次。
解決方案很簡單,就是加一個 isLoading 開關(guān),在請求中的時候,把根據(jù)這個開關(guān)把監(jiān)聽目標(biāo)隱藏掉,等加載渲染結(jié)束之后,再顯示出來,就可以解決這個問題了。具體可以看演示的案例哦~
<div class="loading">
<div ref="loading" v-show="!isLoading"></div>
loading..
</div>
結(jié)語
以異步觀察目標(biāo)元素的方式來完成諸如此類的業(yè)務(wù)比如說分頁加載,觸發(fā)動畫,阻止操作等等都是不錯的選擇,而且從兼容性來看也可以放心在大多數(shù)現(xiàn)代瀏覽器中使用到它。

以上就是異步觀察目標(biāo)元素方式完成分頁加載的詳細(xì)內(nèi)容,更多關(guān)于異步觀察目標(biāo)元素分頁加載的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一文詳解webpack中l(wèi)oader與plugin的區(qū)別
這篇文章主要為大家介紹了一文詳解webpack中l(wèi)oader與plugin的區(qū)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
前端Website?sitemap.xml文件搜索引擎優(yōu)化
這篇文章主要為大家介紹了前端Website的sitemap.xml文件和搜索引擎優(yōu)化實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
JS前端實(shí)現(xiàn)fsm有限狀態(tài)機(jī)實(shí)例詳解
這篇文章主要為大家介紹了JS前端實(shí)現(xiàn)fsm有限狀態(tài)機(jī)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Css-In-Js實(shí)現(xiàn)classNames庫源碼解讀
這篇文章主要為大家介紹了Css-In-Js實(shí)現(xiàn)classNames庫源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12

