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


还想看什么?

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

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
晨米酱1 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
彧azz1 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端