IntersectionObserver
IntersectionObserver
是 JavaScript 中用于监听元素与其祖先元素或视口(viewport)交叉状态的 API,常用于实现懒加载 、无限滚动 、广告曝光统计等功能。以下是其核心概念和用法:
核心概念
- 交叉观察 :检测目标元素与根元素(默认为视口)的交集变化。
- 阈值(Threshold) :交集比例达到多少时触发回调(如
0.5
表示元素显示一半时触发)。 - 异步触发:由浏览器优化后异步执行,不会阻塞主线程。
js
// 创建观察者实例
const observer = new IntersectionObserver(
(entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// 元素进入视口时的操作
console.log(`${entry.target.id} 进入视口`);
observer.unobserve(entry.target); // 停止观察
}
});
},
{
root: null, // 默认为视口
rootMargin: '0px', // 根元素的边距(如 `'10px 0px'`),可扩大或缩小监听范围。
threshold: 0.1 // 元素显示 10% 时触发回调
}
);
// 观察目标元素
const target = document.getElementById('target');
observer.observe(target);
回调参数(entries
) 每个 entry
对象包含以下属性:
isIntersecting
:布尔值,表示元素是否正在交叉。intersectionRatio
:交集比例(0~1)。target
:目标元素。boundingClientRect
:目标元素的位置信息。intersectionRect
:交集区域的位置信息。
常见应用场景
1. 图片懒加载
js
const images = document.querySelectorAll('img[data-src]');
const imgObserver = new IntersectionObserver(
(entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src; // 加载真实图片
img.classList.add('loaded');
observer.unobserve(img);
}
});
},
{ threshold: 0.1 }
);
images.forEach(img => imgObserver.observe(img));
2. 无限滚动
js
const loadMoreObserver = new IntersectionObserver(
(entries) => {
if (entries[0].isIntersecting) {
loadMoreData(); // 加载更多数据
}
},
{ rootMargin: '100px' } // 提前 100px 触发加载
);
loadMoreObserver.observe(document.getElementById('load-more-trigger'));
3. 元素曝光统计
js
const adObserver = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && entry.intersectionRatio >= 0.5) {
trackAdExposure(entry.target.id); // 统计广告曝光
observer.unobserve(entry.target);
}
});
},
{ threshold: 0.5 } // 至少显示 50% 时才统计
);
优点
- 性能优化 :由浏览器原生实现,避免频繁的
scroll
或resize
事件监听。 - 简化开发:无需手动计算元素位置,逻辑更清晰。
- 异步执行:不阻塞主线程,提升页面响应速度。
缺点
- 兼容性 :IE 不支持,需使用 polyfill(如 intersection-observer)。
- 精度限制:无法精确控制像素级别的交叉检测。