JavaScript如何实现图片懒加载_JavaScript如何监听图片进入视口

JavaScript图片懒加载核心是监听图片是否进入视口后才加载真实资源,推荐用IntersectionObserver实现提前加载,不支持时降级为scroll+getBoundingClientRect,并需处理加载失败、布局偏移等优化。

JavaScript 实现图片懒加载,核心是监听图片是否进入视口(viewport),并在进入时才加载其真实图片资源。这能显著减少首屏请求、节省带宽、提升页面初始渲染性能。

使用 IntersectionObserver 监听图片是否进入视口

现代推荐方式是使用 IntersectionObserver API,它原生支持异步监听元素与视口的交叉状态,性能好、写法简洁、无需频繁监听 scroll 或 resize。

  • 将图片的真实地址(如 data-src)暂存于自定义属性中,src 先设为空或占位图
  • 创建 Observer 实例,配置 rootMargin(如 "100px")可实现“提前加载”,让图片在真正进入视口前就开始请求
  • 回调中判断 isIntersecting === true,则设置 img.src = img.dataset.src,并可调用 unobserve() 避免重复触发

兼容性处理:不支持 IntersectionObserver 时降级为 scroll + getBoundingClientRect

对于需兼容 IE 或老版本浏览器的场景,可用传统方式模拟:

  • 将所有待懒加载图片缓存到数组中,绑定 scrollresize 事件(注意节流)
  • 遍历图片,调用 element.getBoundingClientRect() 获取其相对于视口的位置
  • 判断 rect.top 0(即顶部在视口下方、底部在视口上方),满足即加载
  • 加载后从缓存数组中移除该元素,避免重复检查

HTML 结构与基础 JS 示例

结构示例:

@@##@@

简单 Observer 实现:

const lazyImages = document.querySelectorAll('img.lazy');
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
observer.unobserve(img);
}
});
}, { rootMargin: '50px' });

lazyImages.forEach(img => observer.observe(img));
}

补充细节与优化建议

实际项目中还需注意:

  • 加载失败时提供 fallback,例如监听 img.onerror 后显示默认图或错误提示
  • 配合 loading="lazy" HTML 属性(现代浏览器原生懒加载),作为兜底或简化静态资源处理
  • 若图片有宽高比要求,建议提前设置 width/height 或使用 aspect-ratio,防止加载时布局偏移(CLS)
  • 服务端可结合 Client-Hints(如 DPRWidth)动态返回适配尺寸的图片,进一步优化懒加载效果