const lazyLoad = {
mounted(el, binding) {
const {arg={}} = binding
const defaultSrc = arg.default
lazyLoad.init(el, binding.value, defaultSrc)
if (IntersectionObserver) { // 如果浏览器支持IntersectionObserver对象
lazyLoad.observe(el)
} else {
lazyLoad.listenerScroll(el)
}
},
init(el, val, def) {
el.setAttribute('data-src', val);
el.setAttribute('src', def);
},
//监听scroll事件
listenerScroll(el){
const handler = lazyLoad.throttle(lazyLoad.load,1000)
lazyLoad.load(el)
window.addEventListener('scroll',()=>{
handler(el)
})
},
observe(el) {
const io = new IntersectionObserver(entries => {
const realSrc = el.dataset.src // 真实的src
if (entries[0].isIntersecting) { // 如果已经滚动到可视区域
if(realSrc){
el.src = realSrc
el.removeAttribute('data-src')
}
}
})
io.observe(el)
},
load(el) {
const windowH = document.documentElement.clientHeight
const elTop = el.getBoundingClientRect().top
const elBottom = el.getBoundingClientRect().bottom
if (elTop - windowH < 0 && elBottom > 0) { // 说明元素已经进入可见区域
const realSrc = el.dataset.src
if(realSrc){
el.src = realSrc
el.removeAttribute('data-src')
}
}
},
throttle(fn, delay) {
let flag = true
return function(...args){
if(!flag)return
flag = false
setTimeout(function(){
fn.apply(this,args)
flag = true
},delay)
}
}
}
export default lazyLoad
使用:
<template>
<div class="container">
<img v-lazyLoad:[arg]="img">
</div>
</template>
<script>
import defaultSrc from '@/assets/placeholder.png'
export default {
data() {
return {
img: 'https://test.static.iskytrip.com/banner/image/b64-373185381662011942491.jpg',
arg: {
default: defaultSrc
}
}
}
}
</script>