這幾天在作商城首頁的商品列表,商品卡片的數量不少,若是一次性加載那麼多,加載較慢,並且用戶體驗很差。因此使用鼠標無限滾動加載效果更好。 實現滾動加載的方式有不少,有現成的組件 InfiniteScroll,可是一些非主流瀏覽器沒法觸發,仍是本身動手寫一寫吧。javascript
實現滾動加載的核心:滾動條高度 + 瀏覽器窗口高度 >= 內容高度 - 閾值html
document.body.scrollTop
滾動條滾動的距離 (這個有兼容性問題,兼容性寫法)let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop
;window.innerHeight
瀏覽器窗口高度document.body.scrollHeight
內容高度 (兼容性寫法) let bodyHeight = document.body.scrollHeight || document.documentElement.scrollHeight
;v-scroll
directives: {
/** * 滾動加載的自定義指令 */
scroll: {
bind(el, binding, vnode) {
window.addEventListener('scroll', vnode.context.scrollLoad)
},
unbind(el, binding, vnode) {
window.removeEventListener('scroll', vnode.context.scrollLoad)
}
}
},
methods: {
scrollLoad() {
//滾動條高度(頁面被捲去高度)
let scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
//文檔高度
let bodyHeight = document.body.scrollHeight || document.documentElement.scrollHeight;
// 滾動條高度 + 瀏覽器高度 >= 文檔高度 - 閾值
if (scrollTop + window.innerHeight >= bodyHeight - 300) {
// 判斷請求發送標誌位,避免重複請求
if (this.loading) return;
// 加載的頁碼和每次滾動加載的數量,中data中聲明
if (this.listIndex * this.PageQty >= this.total) return;
this.listIndex++
// 獲取商品數據的異步操做
this.getProductList(this.listIndex)
}
}
}
複製代碼
這裏須要注意:java
由於發送請求和滾動事件的方法定義在了組件的
methods
中,須要拿到Vue實例,但在自定義指令裏,不能經過this
拿到Vue實例,而是經過指令鉤子函數的第三個參數vnode
的context
屬性拿node必需要在unbind鉤子中解綁滾動加載事件,不然在其餘頁面也會被觸發。瀏覽器
使用時,由於基於文檔高度和滾動條高度,綁在哪裏無所謂。異步
<template>
<div id="index" v-scroll>
<ul>
<li v-for="(item, index) in productList" :key="index">
</li>
</ul>
</div>
</template>
複製代碼