图片懒加载的三种实现方式:
一、getBoundingClientRect API + Scroll with Throttle + DataSet API
二、IntersectionObserver API + DataSet API
三、vue-lazyload
一、getBoundingClientRect API + Scroll with Throttle + DataSet API
<img data-src="shanyue.jpg">
首先设置一个临时 Data 属性 data-src,控制加载时使用 src 代替 data-src,可利用 DataSet API 实现。
img.src = img.datset.src
那如何判断图片出现在了当前视口呢,根据示例图示意,代码如下,这个就比较好理解了。
// clientHeight 代表当前视口的高度
img.getBoundingClientRect().top < document.documentElement.clientHeight
监听 window.scroll 事件也优化一下
加个节流器,提高性能。工作中一般使用 lodash.throttle 就可以了,万能的 lodash 啊!
_.throttle(func, [wait=0], [options={}])
完整代码(这里没用 lodash.throttle)
<img :data-src="strawberryPic"
class="picClass"
ref="strawberryPic" />
import strawberryPic from '../assets/strawberry.jpg'
data () {
return {
strawberryPic: strawberryPic
}
},
mounted () {
this.listenScorll()
},
methods: {
listenScorll () {
window.addEventListener('scroll', this.imgScroll)
},
imgScroll () {
let obj = this.$refs['strawberryPic'];
let picTop = obj.getBoundingClientRect().top;
let clientHeight = document.documentElement.clientHeight;
console.log('pic', picTop)
console.log('document', clientHeight)
if (picTop - clientHeight <= 0) {
obj.src = obj.dataset.src
}
},
}
二、IntersectionObserver API + DataSet API
方案一使用的方法是:window.scroll
监听 Element.getBoundingClientRect()
并使用_.throttle
节流。
一系列组合动作太复杂了,于是浏览器出了一个三合一事件:IntersectionObserver
API,一个能够监听元素是否到了当前视口的事件,一步到位!
事件回调的参数是 IntersectionObserverEntry的集合,代表关于是否在可见视口的一系列值。
其中,entry.isIntersecting
代表目标元素可见。
const observer = new IntersectionObserver((changes) => {
// changes: 目标元素集合
changes.forEach((change) => {
// intersectionRatio
if (change.isIntersecting) {
const img = change.target
img.src = img.dataset.src
observer.unobserve(img)
}
})
})
observer.observe(img)
完整代码
mounted () {
this.intersectionObserver();
},
methods: {
intersectionObserver () {
let img = this.$refs['strawberryPic'];
const observer = new IntersectionObserver((changes) => {
// changes: 目标元素集合
changes.forEach((change) => {
console.log(change)
// intersectionRatio
if (change.isIntersecting) {
console.log('1')
const img = change.target
img.src = img.dataset.src
observer.unobserve(img)
}
})
})
observer.observe(img)
}
}
三、vue-lazyload
使用vue-lazyload插件:
1、安装插件
npm install vue-lazyload --save-dev
2、在入口文件main.js中引入并使用
import VueLazyload from 'vue-lazyload'
Vue.use(VueLazyload)
3、修改图片显示方式为懒加载(将 :src 属性直接改为v-lazy)