如何判断图片进入视口(图片懒加载原理)

要判断图片是否进入了可视区域,可以使用 滚动监听 或者更常用的 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 是异步的,不会阻塞主线程,也能避免重复计算。
  • 简洁易用:代码更简洁,且可以在浏览器支持的情况下自动处理复杂的交叉检测逻辑。
posted @ 2025-02-17 14:09  脆皮鸡  阅读(109)  评论(0)    收藏  举报