图片懒加载

懒加载,顾名思义,在当前网页,滑动页面到能看到图片的时候再加载图片

故问题拆分成两个:

  1. 如何判断图片出现在了当前视口 (即如何判断我们能够看到图片)
  2. 如何控制图片的加载

方案一: 位置计算 + 滚动事件 (Scroll) + DataSet API

判断图片出现在了当前视口

clientTopoffsetTopclientHeight 以及 scrollTop ,相对图片的高度作比对

监听 window.scroll 事件

控制图片的加载

1
<img data-src="target.jpg" />

首先设置一个临时 Data 属性 data-src,控制加载时使用 src 代替 data-src,可利用 DataSet API 实现

1
img.src = img.datset.src

方案二: getBoundingClientRect API + Scroll with Throttle + DataSet API

判断图片出现在了当前视口

Element.getBoundingClientRect() 方法返回元素的大小及其相对于视口的位置。

getBoundingClientRect示例图

1
2
// clientHeight 代表当前视口的高度
img.getBoundingClientRect().top < document.documentElement.clientHeight;

监听 window.scroll 事件优化

加个节流器,提高性能。(使用lodash)

1
_.throttle(func, [(wait = 0)], [(options = {})]);

方案三: IntersectionObserver API + DataSet API

判断图片出现在了当前视口

IntersectionObserver API(试验性功能),一个能够监听元素是否到了当前视口的事件

事件回调的参数是 IntersectionObserverEntry的集合,代表关于是否在可见视口的一系列值,entry.isIntersecting 代表目标元素可见:

1
2
3
4
5
6
7
8
9
10
11
12
13
const observer = new IntersectionObserver((changes) => {
// changes: 目标元素集合
changes.forEach((change) => {
// intersectionRatio
if (change.isIntersecting) {
const img = change.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
});

observer.observe(img);

方案四: LazyLoading 属性

1
<img src="shanyue.jpg" loading="lazy" />

浏览器兼容性不好