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


还想看什么?

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

相关推荐
带娃的IT创业者3 小时前
TypeScript + React + Ant Design 前端架构入门:搭建一个 Flask 个人博客前端
前端·react.js·typescript
二十雨辰3 小时前
vite如何处理项目中的资源
开发语言·javascript
非凡ghost4 小时前
MPC-BE视频播放器(强大视频播放器) 中文绿色版
前端·windows·音视频·软件需求
Stanford_11064 小时前
React前端框架有哪些?
前端·微信小程序·前端框架·微信公众平台·twitter·微信开放平台
洛可可白4 小时前
把 Vue2 项目“黑盒”嵌进 Vue3:qiankun 微前端实战笔记
前端·vue.js·笔记
学习同学5 小时前
从0到1制作一个go语言游戏服务器(二)web服务搭建
服务器·前端·golang
-D调定义之崽崽5 小时前
【初学】调试 MCP Server
前端·mcp
四月_h6 小时前
vue2动态实现多Y轴echarts图表,及节点点击事件
前端·javascript·vue.js·echarts
文心快码BaiduComate6 小时前
用Zulu轻松搭建国庆旅行4行诗网站
前端·javascript·后端
正义的大古7 小时前
OpenLayers地图交互 -- 章节十八:拖拽旋转和缩放交互详解
javascript·vue.js·openlayers