还有人不知道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 的人(开玩笑的😄)。


还想看什么?

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

相关推荐
gnip8 分钟前
项目开发流程之技术调用流程
前端·javascript
答案—answer9 分钟前
three.js编辑器2.0版本
javascript·three.js·three.js 编辑器·three.js性能优化·three.js模型编辑·three.js 粒子特效·three.js加载模型
转转技术团队22 分钟前
多代理混战?用 PAC(Proxy Auto-Config) 优雅切换代理场景
前端·后端·面试
南囝coding24 分钟前
这几个 Vibe Coding 经验,真的建议学!
前端·后端
gnip37 分钟前
SSE技术介绍
前端·javascript
掘金安东尼1 小时前
蔚来 600 亿研发成本,信还是不信。。
面试·程序员·github
yinke小琪1 小时前
JavaScript DOM节点操作(增删改)常用方法
前端·javascript
枣把儿1 小时前
Vercel 收购 NuxtLabs!Nuxt UI Pro 即将免费!
前端·vue.js·nuxt.js
望获linux1 小时前
【Linux基础知识系列】第四十三篇 - 基础正则表达式与 grep/sed
linux·运维·服务器·开发语言·前端·操作系统·嵌入式软件
爱编程的喵1 小时前
从XMLHttpRequest到Fetch:前端异步请求的演进之路
前端·javascript