还有人不知道IntersectionObserver也可以实现懒加载吗

前言

❝兄弟姐妹们,2025年了,还有人写图片懒加载在监听 scroll 事件的吗?❞ 今天不装了,摊牌了------IntersectionObserver,才是懒加载的正解,而且香到爆!


🧠 什么是懒加载?

简单来说:

"不在屏幕里的东西就不加载,等它快出现在屏幕上再去加载。"

一般可视区域我们分为布局视口视觉视口 ,‌理想视口

  • 布局视口:页面最初的可视区域,通常是浏览器设定的参考尺寸
  • 视觉视口:用户当前实际看到的区域,受缩放和滚动影响
  • 理想视口:移动端浏览器希望开发者使用的推荐宽度

懒加载的情况一般情况称为布局视口

常见用法:

  • 图片懒加载
  • 无限滚动加载
  • 首页瀑布流列表加载
  • 视频、广告、卡片懒加载等

传统写法有多麻烦?

很多教程还在讲这种:

javascript 复制代码
window.addEventListener('scroll', () => {
  // 判断元素是否出现在视口中......
  // 如果出现就加载图片......
  // 还要处理一些边界值以及细节问题,很麻烦
})

而且还得加节流、防抖,处理滚动性能...... 可读性差、性能不优雅、维护烦人!


IntersectionObserver 是啥?

可以看到2019年3月已经大力支持所有浏览器 ,至今已经有六年时间了,坚决不允许还有人不知道IntersectionObserver是做什么的

IntersectionObserver 浏览器原生提供的 API,用来监听一个元素是否出现在视口中。细节说明可以查看官方文档

节能高效、不卡性能、写法优雅。

有点像你是一位摄影师,当你拍人走过的时候,你说停,她就停,摄影师就咔咔两下,照片就有了。


代码示例

html 复制代码
<img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.5053ecdbef05fa7726aa489d27b52e40&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.c5db2c88af1a76f18d0efe02fcded91d&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.c5129de8701c4a933d92cd6bf832b233&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.afe7f6448d6eba0055cd8ce9ac9fdf62&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.e168b9c5da30772083104ed0f4ef0ecf&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.8025ce5a977b3826589022cede69e110&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.a58ae29e32e20a27d498eed19528ee3c&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt="">
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.2049b527600b31b2cd863a380be59848&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.9f51912b8b6c19a9891b380ad526db85&pid=Wdp&w=612&h=304&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
      <img class="img-item" src="" data-original="https://th.bing.com/th?id=ORMS.1b6375ea147b5704f9d073a326e1fc2a&pid=Wdp&w=300&h=156&qlt=90&c=1&rs=1&dpr=1.25&p=0" alt=""/>
js 复制代码
  const io = new IntersectionObserver((entries) => {
      console.log(entries, "entries");

      entries.forEach((entry) => {
        console.log(entry, "entry");

        if (entry.isIntersecting) {
          entry.target.src = entry.target.dataset.original;
          entry.target.removeAttribute("data-original");
          io.unobserve(entry.target);
        }
      });
    });
    const imgs = document.querySelectorAll("img[data-original]");
    imgs.forEach((item) => {
      io.observe(item);
    });

就这么短!不用 scroll,不用节流,也不用 setTimeout!浏览器自动帮你判断这个元素是否可见!


实战场景:列表懒加载

比如一个"发现"页,下面是伪代码逻辑:

js 复制代码
const loadMoreObserver = new IntersectionObserver((entries) => {
  if (entries[0].isIntersecting) {
    loadNextPage()
  }
})

loadMoreObserver.observe(document.querySelector('#load-more-anchor'))

你可以在页面底部加一个 #load-more-anchor 空 div,当它滚进视口就加载下一页。


它还能干嘛?

  • 图片懒加载
  • 无限滚动
  • 动画触发(进场动效)
  • 可见性曝光统计(广告统计)
  • 滚动自动播放视频

简直是滚动相关的全能工具。

arduino 复制代码
new IntersectionObserver(callback, {
  rootMargin: '0px 0px 100px 0px' // 提前 100px 触发
})

为什么现在用它更香了?

  • 所有现代浏览器都支持(IE 不支持,但已经凉了)
  • 性能远优于 scroll 监听 + 计算
  • 写法优雅,代码更干净
  • 容易理解且封装

总结

懒加载不只是"懒",它只是惰性加载,让人眼的视觉看起来更舒服"。

能用浏览器原生机制做的事,就别手动造轮子浪费性能。

如果你今天第一次认识 IntersectionObserver,欢迎点赞收藏;

如果你早就用过,欢迎在评论区嘲笑一下还在 scroll 的人(开玩笑的😄)。


还想看什么?

评论告诉我你想看啥,整!

相关推荐
2601_949817923 小时前
大厂Java进阶面试解析笔记文档
java·笔记·面试
猫猫不是喵喵.4 小时前
layui表单项次大数据量导入并提交
前端·javascript·layui
张小潇4 小时前
AOSP15 WMS/AMS系统开发 - 窗口层级源码分析
android·前端
C雨后彩虹4 小时前
最多等和不相交连续子序列
java·数据结构·算法·华为·面试
whuhewei4 小时前
HTTP1/2/3演变
前端·计算机网络
腹黑天蝎座4 小时前
从零实现一个前端监控系统:性能、错误与用户行为全方位监控
前端·监控
一江寒逸5 小时前
零基础从入门到精通 AI Agent 开发(全栈保姆级教程)附加篇:AI Agent 面试八股文全集
人工智能·面试·职场和发展
爱敲代码的小黄5 小时前
我重新梳理了一遍 RAG,终于明白它不只是接个向量库
后端·面试·agent
久菜盒子工作室5 小时前
面试经验|产品经理|自我介绍
面试·职场和发展·产品经理
Hello--_--World5 小时前
ES13:类私有属性和方法、顶层 await、at() 方法、Object.hasOwnProperty()、类静态块 相关知识点
开发语言·javascript·es13