如何判断图片进入视口(图片懒加载原理)
要判断图片是否进入了可视区域,可以使用 滚动监听 或者更常用的 IntersectionObserver API,后者是一种更加高效且现代的方式。IntersectionObserver 能够监听一个元素是否与视口(可视区域)相交,而不需要手动监听滚动事件。
使用 IntersectionObserver API
// 选择需要懒加载的图片
const images = document.querySelectorAll('img.lazy');
// 创建一个 IntersectionObserver 实例
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
// 判断图片是否进入了可视区域
if (entry.isIntersecting) {
const img = entry.target;
// 将图片的 src 属性替换为真实的图片地址
img.src = img.dataset.src;
// 停止观察这个图片
observer.unobserve(img);
}
});
}, { threshold: 0.1 }); // 可调整的阈值,表示图片至少 10% 进入可视区域才会触发回调
// 开始观察每一张图片
images.forEach(image => {
observer.observe(image);
});
关键要点:
img.lazy是一个添加了lazy类的图片元素,图片的src属性最初是一个占位符,实际图片路径存储在data-src属性中。IntersectionObserver会监听这些图片元素是否进入视口(可见区域)。当图片进入视口时,它的真实图片(存储在data-src属性中)会被加载。- 通过
observer.unobserve(img)停止对已加载图片的观察,避免重复操作。
HTML 示例:
<img class="lazy" data-src="real-image.jpg" src="placeholder.jpg" alt="Lazy Loaded Image">
IntersectionObserver 的选项说明:
threshold: 表示触发回调的条件,取值可以是一个数字或者一个数组。比如0.1表示当至少 10% 的图片区域进入视口时触发回调。root: 可视区域的父元素,默认是浏览器的可视窗口。如果设置了特定的滚动容器元素,可以指定root为该容器。rootMargin: 可视区域的边距,可以用于提前或延迟触发。例如,'0px 0px 100px 0px'会使得图片在距离视口底部 100px 时就开始加载。
使用 IntersectionObserver 的优势:
- 性能优越:相比滚动事件监听,
IntersectionObserver是异步的,不会阻塞主线程,也能避免重复计算。 - 简洁易用:代码更简洁,且可以在浏览器支持的情况下自动处理复杂的交叉检测逻辑。

浙公网安备 33010602011771号