前言
图片懒加载是一个很平常的功能,之前实现的方式基本都是 scrollTop+clientHeight>=offsetTop
那么图片就加载,有一些弊端。
- 监听滚动,要是套很多层怎么办,当然硬写也是可以写的,比较麻烦。
- 每一个需要懒加载的都要去监听滚动,影响性能。
当知道IntersectionObserver
后,我也瞬间明白面试官为什么会问如何实现图片懒加载,你有几种方法,他想听的并不是scrollTop+clientHeight>=offsetTop
,还是太天真,害。这种方法之前也有写过 从理论到代码实操,图片预加载和懒加载 - 掘金 (juejin.cn)
IntersectionObserver
文档: IntersectionObserver - Web API 接口参考 | MDN (mozilla.org)
接下来进入主题IntersectionObserver
,代码也会放在后面。

正文
官方的文档是这样说的。
IntersectionObserver
接口(从属于 Intersection Observer API)提供了一种异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的方法。其祖先元素或视口被称为根(root)。
简单来说,你所观察的元素只要在屏幕的视口中出现,就会触发你所设定的代码。
IntersectionObserver
的基本使用
创建IntersectionObserver
对象
ini
var observer = new IntersectionObserver(callback[, options]);
- callback
- 当元素可见比例超过指定阈值后,会调用一个回调函数,此回调函数接受两个参数:
- 一个
IntersectionObserverEntry
对象的数组,每个被触发的阈值,都或多或少与指定阈值有偏差。 - observer:被调用的
IntersectionObserver
实例。
- 一个
- 当元素可见比例超过指定阈值后,会调用一个回调函数,此回调函数接受两个参数:
- options
- 一个可以用来配置 observer 实例的对象。如果
options
未指定,observer 实例默认使用文档视口作为 root,并且没有 margin,阈值为 0%(意味着即使一像素的改变都会触发回调函数)- root:监听元素的祖先元素
Element
对象,其边界盒将被视作视口。目标在根的可见区域的的任何不可见部分都会被视为不可见。 - 一个在计算交叉值时添加至根的边界盒 (bounding_box (en-US)) 中的一组偏移量,类型为字符串 (string) ,可以有效的缩小或扩大根的判定范围从而满足计算需要。语法大致和 CSS 中的
margin
属性等同; 可以参考 intersection root 和 root margin 来深入了解 margin 的工作原理及其语法。默认值是"0px 0px 0px 0px"。 - 规定了一个监听目标与边界盒交叉区域的比例值,可以是一个具体的数值或是一组 0.0 到 1.0 之间的数组。若指定值为 0.0,则意味着监听元素即使与根有 1 像素交叉,此元素也会被视为可见。若指定值为 1.0,则意味着整个元素都在可见范围内时才算可见。可以参考阈值来深入了解阈值是如何使用的。阈值的默认值为 0.0。
- root:监听元素的祖先元素
- 一个可以用来配置 observer 实例的对象。如果
通常使用方式,options
不用设置,看需求
js
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// console.log('元素进入视口');
} else {
// console.log('元素离开视口');
}
});
});
observer.observe(targetElement);
常用的实例方法
observe()
向IntersectionObserver
对象监听的目标集合添加一个元素。
ini
IntersectionObserver.observe(targetElement);
targetElement
- 可见性区域被监控的元素
element
。 此元素必须是根元素的后代 (如果根元素为视窗,则该元素必须被当前文档包含)。
- 可见性区域被监控的元素
disconnect()
终止对所有目标元素可见性变化的观察
ini
intersectionObserver.disconnect();
unobserve()
停止对一个元素的观察
ini
IntersectionObserver.unobserve(target);
target
- 要取消观察的目标,如果没有提供,方法不做任何事情,也不会抛出异常。
懒加载图片
设置props

核心懒加载代码
你只管使用IntersectionObserver
就好,剩下的它会处理
图片加载完回调

结语
仓库地址:function-realization: 实现一些有趣的功能 (gitee.com)。
感兴趣的可以去试试。