实现图片懒加载

1,485 阅读1分钟

简单介绍: 首先将页面上的图片的 src 属性设为空字符串,而图片的真实路径则设置在data-src属性中, 判断我们的懒加载的图片是否进入可视区域,如果图片在可视区内将图片的 src 属性设置为data-src的值,这样就可以实现延迟加载。

实现步骤

  • 通过Intersection Observer监听图片是否在可视区域。

  • 在img标签中定义data-src属性用于存放真实的图片的真实地址,src属性存放我们替换的图片。

  • 当监听到图片dom进入可视区域,我们就将当前imgdom中的src换成data-src中的值。然后停止对元素的监听IntersectionObserver.unobserve(target);

  • 当组件卸载的时候,终止对所有目标元素可见性变化的观察。intersectionObserver.disconnect();

代码实现

function lazyImg(dom) {
      const observer = new IntersectionObserver((entires) => {
        entires.forEach(item => {
          if (item.isIntersecting) {
            // 获取真实的图片地址
            const imgSrc = item.target.getAttribute("data-src");
            // 将图片地址赋值给src属性。
            item.target.setAttribute("src", imgSrc)
            // 将该元素停止监听
            observer.unobserve(item.target);
          }
        })
      })
      if (dom.length) {
        [...dom].forEach(item => {
          observer.observe(item)
        });
      }
    }

一个懒加载事例

  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/1.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/2.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/3.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/4.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/5.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/6.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/7.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/8.jpg">
  </div>
  <div>
    <img class="img" src="./img/zhenshang.png" data-src="./img/9.jpg">
  </div>
  <script>
    function lazyImg(dom) {
      const observer = new IntersectionObserver((entires) => {
        entires.forEach(item => {
          if (item.isIntersecting) {
            // 获取真实的图片地址
            const imgSrc = item.target.getAttribute("data-src");
            // 将图片地址赋值给src属性。
            item.target.setAttribute("src", imgSrc)
            // 将该元素停止监听
            observer.unobserve(item.target);
          }
        })
      })
      if (dom.length) {
        [...dom].forEach(item => {
          observer.observe(item)
        });
      }
    }
    // 获取图片dom元素
    const imgDom = document.getElementsByClassName("img");
    lazyImg(imgDom)
  </script>

动画.gif

懒加载单一的背景图片

就是通过判断当前图片的url是否请求回来,如果很长时间才请求回来,我们就需要先做一下过度,提高用户体验。

function lazyImg() {
  return new Promise((resolve, reject) => {
          const image = new Image();
          image.src = '图片的真实地址'
          // 图片加载成功
          image.onload = () => {
            // 传出true表示图片加载完毕
            resolve(true)
          }
          // 
           image.onerror = () => {
              reject(false);
            };
        })
}

// 外部接收到flag来做相应的处理。

单图片懒加载事例

 <style>
    img {
      display: none;
    }
  </style>
  
  <p id="p">正在加载图片....</p>
  <img src="" alt="" id="img" src-data="./sun.jpg">
  <script>
    function loadImageAsync(url) {
      return new Promise(function (resolve, reject) {
        const image = new Image();

        image.onload = function () {
          resolve(true);
        };

        image.onerror = function () {
          reject(false);
        };
        image.src = url;
      });
    }

    let flag = false;
    const img = document.getElementById("img");
    const p = document.getElementById("p");


    loadImageAsync("./sun.jpg").then(res => {
      flag = res;
      if (flag) {
        p.style.display = 'none'
        img.style.display = 'inline-block';
        const url = img.getAttribute("src-data");
        img.setAttribute("src", url)
      }
    })
  </script>

stream.gif 原图

sun.jpg