前言
❝兄弟姐妹们,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
的人(开玩笑的😄)。
还想看什么?
评论告诉我你想看啥,整!