intersectionobserver 是浏览器原生异步监听元素进出视口的 api,不触发重排重绘,通过异步回调、批量处理和空闲调度实现高性能可见性检测,适用于懒加载、曝光埋点等场景。

IntersectionObserver 是浏览器原生提供的异步监听元素是否进入(或离开)视口的 API,它不依赖滚动事件、不触发重排重绘,性能远优于手动实现的可见性检测。
核心机制:异步回调 + 懒加载友好
Observer 不在主线程实时计算,而是在浏览器空闲时批量触发回调,避免滚动卡顿。每次触发时传入的是 IntersectionObserverEntry[] 数组,每个 entry 包含目标元素与根容器的交叉状态(如 isIntersecting、intersectionRatio、boundingClientRect 等)。
- 回调函数默认在下一个宏任务中执行,但实际调度由浏览器控制,开发者无法精确指定时机
- 即使元素短暂闪现(比如快速滚动),只要满足阈值条件,仍会收到通知
- 适合图片懒加载、无限滚动、曝光埋点、动画触发动效等场景
基本用法:创建 + 观察 + 停止
只需三步即可启用:
-
创建实例:可传入回调函数和配置对象(
root、rootMargin、threshold) - 调用 observe():传入一个 DOM 元素,开始监听其交叉状态
- 调用 unobserve() 或 disconnect():前者停止监听单个元素,后者彻底清空所有监听并释放资源
示例:
const io = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('元素已可见', entry.target);
// 加载图片、启动动画、上报曝光...
io.unobserve(entry.target); // 用完即弃,避免重复触发
}
});
}, {
threshold: 0.1, // 元素 10% 进入视口时触发
rootMargin: '0px 0px -50px 0px' // 向上扩展 50px 触发区域
});
io.observe(document.querySelector('.lazy-img'));
关键配置项说明
配置影响触发时机和精度:
-
root:指定滚动容器,默认为浏览器视口;可设为某个父级元素(需设置
overflow且有高度) - rootMargin:类似 CSS margin,用于扩大或缩小“视口”范围,支持 px / % / em,常用来提前加载
-
threshold:可为数字(0–1)或数字数组;例如
[0, 0.25, 0.5, 0.75, 1]表示在元素 0%、25%…100% 可见时分别通知
注意事项与常见陷阱
使用中容易忽略但影响功能的关键点:
- 被观察元素必须已存在于 DOM 中,动态插入后需再次调用
observe() - 若
root是非视口元素,该元素必须有明确的高度且内容可滚动,否则可能始终不触发 -
intersectionRatio在元素完全不可见时为 0,完全可见时为 1;但受rootMargin影响,可能大于 1 - 不要在回调中直接修改被观察元素样式(尤其触发重排),建议用
requestIdleCallback或节流处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











