news 2026/5/1 8:49:07

利用MutationObserver+IntersectionObserver实现图片懒加载

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
利用MutationObserver+IntersectionObserver实现图片懒加载

利用MutationObserver+IntersectionObserver实现图片懒加载

前言

  • 图片懒加载这并不陌生,对于前端性能优化来讲这是必经之路,
  • 我们之前做图片懒加载都是用滚动监听实现,核心逻辑是监听scroll/resize/load事件->防抖后遍历所有懒加载图片->通过getBoundingClientRect()计算图片位置,判断是否进入视口->加载图片
  • 伪代码
window.addEventListener('scorll',debounce(()=>{document.querySelectorAll('img[data-lazy-src]').forEach(img=>{constrect=img.getBoundingClientRect()if(rect.top<window.innerHeight+200&&rect.bottom>0){img.src=img.dataset.lazySrc}})}))
  • 这么做可以实现么,可以,但是有没有缺点呢,有
    1. 高消耗,scroll事件高频触发,及时使用了防抖,仍有频繁执行;且每次触发需要遍历所有懒加载图片,调用getBoundingClientRect;无法自动停止监听,及时图片已加载,仍会参与遍历
    1. 动态图片无法覆盖,无法捕获异步新增的图片,需要手动调用检查函数
    1. 开发成高,需要手动实现防抖、视口判断、边界条件(如提前加载、窗口缩放);需要手动处理动态图片,容易遗漏动态图片;需要手动避免重复加载
    1. 精度低,视口判断依赖getBoundingClientRect(),受CSS变形,滚动条等影响,容易计算错误;
    1. 稳定性差,因为有防抖延迟,可能导致图片延迟加载,高频滚动是js阻塞,可能导致页面卡顿
  • 等等,会有一系列的问题,而这些问题的根源在于判断图片是否进入视口时需要用scroll去监听
  • 那有没有不需要通过scroll去监听就能判断图片是否进入视口的方法呢,真好,还真有
  • 这个玩意叫InterSectionObserver,翻译为交叉观察器

IntersectionObserver

  • 这是个啥玩意呢,他的作用就是目标元素与视口产生一个交叉区,看看这个交叉区的比率是多少,如果是0,则不可见,100则完全可见(0-100)则部分可见
  • 怎么用呢,直接上代码
constobserver=newInterSectionObserver((entries,observer)=>{entries.forEach(entry=>{if(entry.inIntersecting){console.log('元素进入视口')}})})observer.oberve(document.qerySelector('target'))
  • 构造函数new IntersectionObserver(callback,options),callback是回调函数
  • options是配置项
  • 主要有三个配置项,root,相对哪个容器进行检测
  • rootMargin,扩展和收缩检测区域,可以理解为预支量,做预加载使用
  • threshold,触发回调的交叉比例
参数类型默认值说明
rootElement nullnull(viewport)相对哪个容器检测(如滚动容器)
rootMarginstring“0px”扩展/收缩检测区域(类似 margin,支持百分比)
hresholdnumber number[]0触发回调的交叉比例(0~1 或 [0, 0.5, 1])
  • callback中(entry)的信息如下
time:45325//触发时间rootBounds:DOMRectReadonly//root的边界boundingClientRect:DOMRect//目标元素边界intersectionRect:DOMREct//交叉区域intersectionRatio:05//交叉比例isIntersecting:true//是否相交intersectionRatio>thresholdtarget:element//被观察者对象
  • 讲完了IntersectionObserver,上篇文章我们还讲了MutationObserver,现在用这两个设计一个图片懒加载的实现

图片懒加载

设计思路

  • 我们理一下,我们要干这么几件事

    1. 创建视口监听器和动态监听器
    1. 处理页面上初始IMG
    1. 处理动态新增的IMG
  • 上个详细的流程图

  • 为了更好的管理和组织,我们可以设计一个类lazyImagesLoder

  • 里面有上述的5个基本方法和4个基本属性

  • 基本属性包括配置属性config,视口实例intersectionObserver,DOM监听实例mutationObserver以及防止重复监听的容器observedImgs

  • 接下来就是代码组织了

  • 上代码

<!-- 懒加载图片:用><imgdata-lazy-src="1.jpg"alt="示例图片1"/><imgdata-lazy-src="2.jpg"alt="示例图片2"/><!-- 动态生成的图片(也会被监听) --><buttononclick="addDynamicImg()">新增图片</button
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 13:41:58

2025链游白皮书:从边缘狂欢到主流文明的三大跃迁密码

引言&#xff1a;一场被低估的数字革命当《塞尔达传说》的玩家为解救公主穿越海拉鲁大陆时&#xff0c;他们或许不会想到&#xff0c;2025年的链游世界里&#xff0c;一位菲律宾玩家正通过《星际矿工3.0》的虚拟矿场赚取真实收入&#xff0c;用游戏内代币支付房租&#xff1b;非…

作者头像 李华
网站建设 2026/4/28 6:17:55

Miniconda-Python3.9环境下实现PyTorch模型灰盒测试流程

Miniconda-Python3.9环境下实现PyTorch模型灰盒测试流程 在深度学习项目从实验走向落地的过程中&#xff0c;一个常被忽视却极其关键的环节是&#xff1a;如何确保你拿到的模型&#xff0c;在不同机器、不同时间运行时&#xff0c;行为始终如一&#xff1f; 这不只是“能不能跑…

作者头像 李华
网站建设 2026/4/26 3:30:10

基于单片机的LED点阵显示屏设计

基于单片机的LED点阵显示屏设计 第一章 绪论 传统显示设备中&#xff0c;LED数码管仅能显示数字与简单符号&#xff0c;液晶显示屏在强光下可视性差&#xff0c;难以满足户外信息展示、动态提示等场景需求。LED点阵显示屏通过多颗LED组成点阵矩阵&#xff0c;可灵活显示字符、图…

作者头像 李华
网站建设 2026/4/29 6:51:13

抱歉,系统超时,请稍后重试。

&#x1f4dd; 博客主页&#xff1a;jaxzheng的CSDN主页 超越数据孤岛&#xff1a;医疗数据科学在心理健康领域的隐私-效用平衡之道目录超越数据孤岛&#xff1a;医疗数据科学在心理健康领域的隐私-效用平衡之道 引言&#xff1a;数据洪流中的隐秘困境 一、技术应用场景&#x…

作者头像 李华
网站建设 2026/4/29 22:05:49

震惊!原来微调才是大模型的“内功心法“,小白也能秒变“调参侠“!从入门到实战,手把手教你打造专属AI助手!

大家一定接触过不少大模型&#xff08;LLM&#xff09;&#xff0c;对ChatGPT、DeepSeek、Qwen等可以说是耳熟能详。这些通用大模型虽然可以拿来直接使用&#xff0c;但是对于一些“私域”的信息无法触及到&#xff0c;缺少相应的训练数据&#xff0c;普遍面临 “水土不服” 的…

作者头像 李华