vue 图片懒加载指令实现

1,166 阅读2分钟

图片懒加载是一个很实用且节约资源的优化方案,其核心思想是一个长图片列表页面,我们不加载全部的图片,只有当我们向下滚动的时候图片资源才被请求到,进入页面的时候,只请求可视区域的图片资源这也就是懒加载。

这里可以使用Web API中的 **IntersectionObserver****接口 **来实现功能:

developer.mozilla.org/zh-CN/docs/…

IntersectionObserver接口 (从属于Intersection Observer API) 
提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。
祖先元素与视窗(viewport)被称为根(root)。

简单来说就是通过这个api我们可以通过观察者模式对页面的某一元素进行观察,

/**
创建一个新的IntersectionObserver对象,
当其监听到目标元素的可见部分穿过了一个或多个阈(thresholds)时,会执行指定的回调函数。
*/
var observer = new IntersectionObserver(callback, options);

在回调函数内我们可以直到当前监听的元素是否已经出现在可视区域,此时更换这个元素的src

具体实现代码:

import B_gray from '../../assets/images/B_gray.png'; // 原始占位图

export const lazyLoad = {
    bind: function (el, binding) {
        // ie浏览器没有IntersectionObserver接口        
        if (IntersectionObserver) {
            let targetSrc = el.src; // 记录img原本要加载的图片地址            
            el.src = B_gray; // 将图片更换为占位图            
            // 创建一个IntersectionObserver对象            
            let lazyImageObserver = new IntersectionObserver((entries) => { // 开始监听后的回调函数                
                    entries.forEach((entry) => {
                    if (entry.intersectionRatio > 0) { // 当前元素在视窗内可见
                        el.src = targetSrc; // 替换当前元素的src为目标图片地址                        
                        lazyImageObserver.unobserve(el); // 使IntersectionObserver停止监听特定目标元素。释放资源
                    }
                })
            })
            lazyImageObserver.observe(el); // 使IntersectionObserver开始监听一个目标元素。
        }
    }
}

在main.js里注册这个指令后即可使用

  <img :src="photoListItem.photoSrc" v-lazyLoad />

假设我们有一个长图片列表,此时当页面滚动到对应元素所在区域后才会加载photoSrc,加载成功前该img.src是我们本地的占位图