<template>
<div class="intersection">
<ul>
<li v-for="(item, index) in goodsData" class="intersection-item" :data-key="item.offerId"></li>
</ul>
</div>
</template>
//可以放在mounted内,或者页面请求数据渲染完的操作内根据实际放调用位置
this.intersectionFn()
data() {
return {
observer:null
}
},
methods:{
intersectionFn() {
// 创建IntersectionObserver实例
const intersection = document.querySelector('.intersection')
this.observer = new IntersectionObserver(
entries => {
let newdata = []
entries.forEach(entry => {
if (entry.isIntersecting) {
// 元素进入可视区域,执行相应逻辑
const item = this.goodsData.find(item => item.offerId === entry.target.dataset.key)
if (item && !item.ciphertext) {
// 标记该元素已经请求过
this.$set(item, 'ciphertext', true)
newdata.push(item)
this.observer.unobserve(entry.target)
}
}
})
//当滚动太快会造成一个接口请求的数据太多,需要拆分开请求
if (newdata.length) {
let productIdsChunk = []
let productIdsArray = newdata.map(v => {
return v.offerId
})
productIdsChunk = this.chunkArray(productIdsArray, 6)
for (const item of productIdsChunk) {
this.getEncryptOrderSupportChannelFn(item)
}
}
},
{
root: intersection, // 使用viewport作为根
rootMargin: '60px', // 在viewport之外60px时触发回调
threshold: 0.1 // 交叉比例达到10%时触发回调
}
)
// 监听所有带有.intersection-item类的元素
const elements = document.querySelectorAll('.intersection-item')
elements.forEach(element => this.observer.observe(element))
},
async getEncryptOrderSupportChannelFn(productIds) {
let params = { productIds }
let data = await xxxxxxxxxxxx(params)
this.goodsData.forEach(val => {
data.forEach(item => {
if (val.offerId == item.productId) {
val.data= item.data
}
})
})
this.$forceUpdate()
},
chunkArray(array, size) {
const result = []
while (array.length > 0) {
result.push(array.splice(0, size))
}
return result
},
},
beforeDestroy() {
if (this.observer) {
this.observer.disconnect()
this.observer = null
}
}