IntersectionObserver 实现图片懒加载(lazyLoad)

实现图片懒加载

IntersectionObserver
demo https://codepen.io/liar0320/full/JjRVMOP

window.onload = () => {
  var eles = document.querySelectorAll("img");

  let loadInstance = loadImageInView({
    loadingImg: "http://placekitten.com/100/100"
  });

  loadInstance(eles);
};

/** 加载试图内的图片
 * @params { HtmlElement } eles
 * @example  <img data-src="xxx.jpg" />
 */
function loadImageInView({ errorImg, loadingImg } = {}) {
  /**
   * @param { "error" | "loading" } type
   * @param { HTMLELEMENT } el
   */
  function setDefaultImage(type, el) {
    switch (type) {
      case "error":
        errorImg ? (el.src = errorImg) : console.error("加载图片失败");
        break;
      case "loading":
        loadingImg ? (el.src = loadingImg) : console.info("请设置loading图片");
        break;
      default:
        break;
    }
  }

  function loadImg(url) {
    let img = new Image();
    img.src = url;
    return new Promise((resolve, reject) => {
      img.onload = () => {
        resolve(img.src);
      };
      img.onerror = (e) => {
        reject(e);
      };
    });
  }

  // 监听回调
  var callback = (entries) => {
    entries.forEach((item) => {
      // 出现到可视区
      if (item.intersectionRatio > 0) {
        var ele = item.target;
        var imgSrc = ele.getAttribute("data-src");
        if (imgSrc) {
          setDefaultImage("loading", ele);
          // 预加载
          loadImg(imgSrc)
            .then((src) => {
              ele.src = src;
            })
            .catch((err) => setDefaultImage("error", ele));
          // 加载过清空路径,避免重复加载
          ele.removeAttribute("data-src");
        }
        observer.unobserve(item.target);
      }
    });
    // if (observer.takeRecords().length === 0) {
    //   observer.disconnect();
    //   observer = null;
    // }
  };
  var observer = new IntersectionObserver(callback);

  /** 加载试图内的图片
   * @params { HtmlElement } eles
   * @example  <img data-src="xxx.jpg" />
   */
  return function addEles(eles) {
    // 列表元素加入监听
    eles.forEach((item) => {
      observer.observe(item);
    });
    return observer;
  };
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值