定义自定义指令js
原理就是一开始不给src附图片地址的值,等到进入指定区域再给它赋值。
这里用到了一个接口IntersectionObserver
IntersectionObserver接口(从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。
当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。
思路分析:
①导入默认显示的图片,在加载不出来图片信息时使用
②通过directive指令,定义自定义指令的名称为lazyload,vue3规则是使用mounted函数(vue2是inserted函数),元素插入后才能获取到dom元素,才能使用 intersectionobserve进行监听进入可视区, el 是图片元素, binding.value 图片地址
③new一个IntersectionObserver实例,在目标元素进入可视区之前对元素进行监听IntersectionObserver.observe()方法就是使IntersectionObserver开始监听一个目标元素。这里使用observer实例
④当目标元素进入可视范围,那么就取消对其的监听IntersectionObserver.unobserve()使IntersectionObserver停止监听特定目标元素。
⑤如果加载不出图片信息,那么就使用导入的默认图片,如果可以加载出来那么就将图片地址赋值给图片元素的src属性
⑥threshold(阈 yu :引申为界限或范围)表示进入可视区域的比例,用来控制加载时机
⑦关键一步,就是一定要记得将这个指令挂载到main.js文件中,成为全局指令
⑧使用时 将 :src用v-lazyload替换
import defaultImg from '@/assets/images/200.png'
const defineDirective = (app) => {
// 图片懒加载指令
app.directive('lazyload', { mounted (el, binding) {
const observer = new IntersectionObserver(([{ isIntersecting }]) => {
if (isIntersecting) {
observer.unobserve(el)
el.onerror = () => { el.src = defaultImg }
el.src = binding.value}
} , { threshold: 0.01 })
observer.observe(el) } })
}