功能介绍
利用IntersectionObserver API实现,主要功能
- 图片懒加载
- 传递一个回调函数,该回调函数会在图片出现时触发,并接收显示的元素。
代码展示
<template>
<div class="test h-[4000px] bg-slate-400 ">
<div class="wrapper flex flex-col mx-auto bg-neutral-200 h-full w-[500px] ">
<img v-for="item of arr " v-load="{src:item,root:null,cb:loadDone}" alt="风景图"/>
</div>
</div>
</template>
<script setup lang='ts'>
const loadDone = (el:HTMLElement) => {
console.log(el,'执行回调')
}
const arr = [
'../../../src/assets/scenery/scene1.jpg',
'../../../src/assets/scenery/scene2.jpg',
'../../../src/assets/scenery/scene3.jpg',
'../../../src/assets/scenery/scene4.jpg',
'../../../src/assets/scenery/scene5.jpg',
'../../../src/assets/scenery/scene6.jpg',
'../../../src/assets/scenery/scene6.jpg',
'../../../src/assets/scenery/scene6.jpg',
'../../../src/assets/scenery/scene6.jpg',
'../../../src/assets/scenery/scene6.jpg',
'../../../src/assets/scenery/scene6.jpg',
]
</script>
<style lang='scss' scoped>
img{ width: 100%; height: 500px; }
</style>
let observe = false
var elementArr = [] as { el: HTMLElement, src: string, cb: Function | null; }[]
const options = {
threshold: [0],//threshold:属性决定相交比例为多少时,触发回调函数。取值为 0 ~ 1,或者 0 ~ 1的数组。
rootMargin: "0px",//rootMargin: 类似于 CSS 的 margin 属性。用来缩小或扩大 rootBounds,从而影响相交的触发
root: null,//root:设置监视器的根节点,不传则默认为视口。
}
const observers = new IntersectionObserver(isoCallback,options)
function useLoadDirective() {
return {
created(el:HTMLElement,binding:any,vnode:any) {
elementArr.push({ el, src: binding.value.src,cb: binding.value.cb})
},
mounted(el:HTMLElement,binding:any) {
if (!observe) {
if(binding.value.root)options.root = binding.value.root
startObserve()
observe = true
}
},
}
}
function isoCallback(entries:any) {
entries.forEach((element:any,index:number) => {
if (element.isIntersecting) {
elementArr.forEach(e => {
if (e.el == element.target) {
element.target.setAttribute('src', e.src)
e.cb && e.cb(element.target)
}
});
observers.unobserve(element.target)
}
});
}
function startObserve() {
elementArr.forEach(v => [
observers.observe(v.el)
])
}
useLoadDirective.dName = 'load'
export default useLoadDirective