JavaScript中的Intersection Observer API
字数 523 2025-11-08 10:03:34
JavaScript中的Intersection Observer API
描述
Intersection Observer API 提供了一种异步观察目标元素与祖先元素或视口(viewport)交叉状态的方法。它可以高效地监测元素是否进入或离开可视区域,常用于实现图片懒加载、无限滚动、曝光统计等功能。
核心概念
- 交叉比例(intersection ratio):目标元素与根元素的相交面积占总面积的比例
- 阈值(threshold):触发回调函数的交叉比例值
- 根元素(root):作为参考框的祖先元素,默认为浏览器视口
创建观察器
// 创建观察器实例
const observer = new IntersectionObserver(callback, options);
options配置参数详解
const options = {
root: null, // 根元素,null表示视口
rootMargin: '0px', // 根元素的外边距,用于扩大或缩小交叉区域
threshold: [0, 0.5, 1] // 阈值,当交叉比例达到这些值时触发回调
};
回调函数结构
const callback = (entries, observer) => {
entries.forEach(entry => {
// entry包含目标元素的交叉信息
console.log(entry.target); // 被观察的元素
console.log(entry.isIntersecting); // 是否在交叉区域内
console.log(entry.intersectionRatio); // 当前交叉比例
});
};
完整使用示例:图片懒加载
// 创建观察器
const lazyImageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
// 将data-src的值赋给src
img.src = img.dataset.src;
// 图片加载后停止观察
img.onload = () => observer.unobserve(img);
}
});
}, {
threshold: 0.1, // 当图片10%进入视口时加载
rootMargin: '50px' // 提前50px开始加载
});
// 观察所有懒加载图片
document.querySelectorAll('img[data-src]').forEach(img => {
lazyImageObserver.observe(img);
});
高级应用:无限滚动
let page = 1;
const sentinel = document.getElementById('sentinel'); // 哨兵元素
const infiniteScrollObserver = new IntersectionObserver(async (entries) => {
if (entries[0].isIntersecting) {
// 加载更多内容
const newContent = await loadMoreContent(page++);
appendContent(newContent);
}
});
infiniteScrollObserver.observe(sentinel);
性能优势
- 异步执行:不阻塞主线程
- 批量处理:多个交叉变化在一次回调中处理
- 自动优化:浏览器内部优化交叉检测
注意事项
- 观察器创建后需要手动调用
observe()开始观察 - 使用
unobserve()停止观察特定元素 - 使用
disconnect()停止所有观察 - 根元素必须是目标元素的祖先元素
Intersection Observer API 解决了滚动相关性能问题,是现代化Web开发中的重要工具。