这里有两个重点,大家需要注意: 问题一:如何判断元素是否进入可视区域? 问题二:如何判断图片加载成功或失败了? 这两个问题的答案后文会提到,大家继续往下阅读 最终实现的就是这样的效果 也可以去笔者的个人网站上,看效果图:http://ashuai.work:8888/#/imgLazyload 推荐使用vue-lazyload插件各方面都很优化, 官方地址:https://www.npmjs.com/package/vue-lazyload 使用步骤,这里笔者就不赘述了,上述的效果图,也是通过这个vue-lazyload插件实现的,对应代码,在笔者的GitHub仓库中: https://github.com/shuirongshuifu/elementSrcCodeStudy/blob/main/src/views/imgLazyload.vue 写一个自定义指令,便于逻辑复用 麻烦一些的方案:监听拥有滚动条的scroll事件,去计算元素距离拥有滚动条的位置,这里笔者总结了一个公式: 相关代码案例,请看笔者的这篇文章: IntersectionObserver是一个非常强大的api,可以观测很多东西的变化,very good,在浏览器版本不断更新迭代的现在,其兼容性已经非常不错了,大家可以放心使用。 关于IntersectionObserver的语法,笔者不赘述了,咱们直接上自定义指令代码 自定义指令代码 使用代码 使用的话,很简单,直接: 注意使用自定义指令别忘了要注册哦 最后,烦请各位道友去笔者的GitHub仓库看看,如果觉得对您有一点点帮助的话,不妨不吝star 自定义指令的完整代码也在笔者的GitHub仓库中哦: https://github.com/shuirongshuifu懒加载问题描述
懒加载问题解决思路
图片懒加载效果
解决方案
方案一 插件就是好!vue-lazyload
方案二 自己手写一个自定义指令v-lazyload
如何判断元素是否进入视口了?
使用IntersectionObserver类构造函数,去判断元素是否进入视口
// let loadimage = "http://ashuai.work:10000/imgGifSrc/loading.gif" // 服务器加载中图片
// let errorimage = "http://ashuai.work:10000/imgGifSrc/error.gif" // 服务器加载中图片
let loadimage = require('../../assets/imgLazyload/loading.gif') // 本地加载中图片
let errorimage = require('../../assets/imgLazyload/error.gif') // 本地加载失败图片
export default {
inserted(el, binding, vnode) {
// 1. 先让图片显示加载中...
el.src = loadimage.default
// 2. 实例化一个:观察检测者
const observer = new IntersectionObserver((entries) => {
// 4. 在观察监测者的对应执行函数中获取到isIntersecting属性(是否交叉)
let isIntersecting = entries[0].isIntersecting
// 5. 如果交叉了,就让其去加载对应src的真正的地址
if (isIntersecting) {
el.src = binding.value
// 6. 加载成功就不用管它
el.onload = (res) => console.log('加载成功', res);
// 7. 加载失败了就去做一个错误图片的占位
el.onerror = (err) => {
console.log('加载失败', err);
el.src = errorimage.default
}
// 8. 无论加载成功或失败,都停止观察任务了
observer.unobserve(el)
}
})
// 3. 让这个观察检测者去观察对应img标签图片
observer.observe(el)
},
}
<img class='imgLazy' v-lazyload="'http://ashuai.work:10000/imgSrc/doupo.png'" />
<img class='imgLazy' v-lazyload="'http://ashuai.work:10000/imgSrc/douluo.png'" />
<img class='imgLazy' v-lazyload="'http://ashuai.work:10000/imgSrc/tunshi.png'" />