IntersectionObserver实现图片懒加载(超详细!)

2023-11-03

关于IntersectionObserver 官方上说明是提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)

具体的内容可以参考官网解释:https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver

这里我们主要来用IntersectionObserve来实现图片的懒加载。

图片的懒加载原理可以分为三步 :

  1. 我们先定义好img元素,我们也可以通过DOM动态添加,可以预先定义好img元素,并给他们一个基础的加载的图片作为公共图片。
  2. 给每个img元素加上data-src来存放真正图片的资源。
  3. 我们通过图片在整个界面的高度位置来和目前可视区域的高度进行比较,如果在可是区域内就进行图片资源的加载,不然就先不加载,从而提高性能。

在这里我们通过IntersectionObserve来实现图片懒加载。IntersectionObserver是浏览器原生提供的构造函数,他支持一个回调函数和,一个可选参数。

const intersectionObserve = new IntersectionObserver(callback, option)

callback的回调函数用来 处理浏览器可视区域的变化,option是一个可选的配置对象。

callback():

  当目标元素可视性变化时就会执行的函数。

option:

配置选项,其中包括root, rootMargin, thresholds

  1.   root: 所监听对象的具体祖先元素,若未指定则默认顶级元素
  2.   rootMargin: 计算交叉时添加到根边界盒的矩形偏移量,可以有效的放大和缩小根的判定范围。
  3.   thresholds: 一个阈值数组每个阈值都是交叉区域和边界区域的比例,当监听对象的可视部分穿过阈值时就会指向指定的回调函数。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Intersection</title>
</head>
<body>
  <h2>图片列表</h1>
    <ul>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP.jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (1).jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (2).jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (3).jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (4).jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP.jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (1).jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (2).jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (3).jpg" alt="" /></li>
      <li><img src="imgs/timg.gif" data-src="imgs/OIP (4).jpg" alt="" /></li>
    </ul>
</body>
<script>
    const root = document.getElementsByTagName('ul')[0]
    const options = {
          root: root,
// 这里是一个数组可以指定多个比例类似[0.25, 0.5, 0.75, 1]
          threshold: [0],//交会处
          rootMargin:"0px"//对视口进行收缩和扩张
      }
  const lazyIntersection = new IntersectionObserver(entires => {
  // entires为监听的节点数组对象
    entires.forEach((item,index) => {
      console.log(item)
      // console.log(item.target, item.isIntersecting? '可见': '不可见')
// isIntersecting是当前监听元素交叉区域是否在可视区域指定的阈值内返回的是一个布尔值
      if(item.isIntersecting) {
        console.log('可见')
        item.target.src = item.target.getAttribute('data-src')
    // 这里资源加载后就停止进行观察
        lazyIntersection.unobserve(item.target)
      }
      // console.log(item)
    })
  }, options)
 // doucument.getElementsByTagName()获取的是一个元素DOM节点的伪数组,无法进行数组的遍历
 // 我们可以使用Array.from()将伪数组转化为真数组进行数组操作
  let data = Array.from(document.getElementsByTagName('img'))
  data.forEach(item => {
// observe用来观察指定的DOM节点
     lazyIntersection.observe(item)
  })
</script>
<style>
  * {
    margin: 0;
    padding: 0;
  }
  ul {
    height: 1000px;
    overflow-y: scroll;
  }
  ul li {
    list-style: none;
    margin-bottom: 10px;
    text-align: center;
  }
  img {
    min-height: 900px;
  }
</style>
</html>

在这里我们通过li元素定义了几个img这里的图片就用想相同的。

由于要实现图片懒加载所以在这里我们需要给img元素定义一个data-src来存放加载图片作为公共图片来增强用户体验。我们先定义需要懒加载的图片的父元素来作为根节点,在这里我们拿ul作为根节点。

我们通过遍历img数组对象来给每一个元素进行监听,在判断isIntersecting,如果为true则就进行加载指定图片资源,当加载完成后就停止监听该节点。

需要注意的是,这里我们需要给一开始的img元素来指定一个宽高。如果我们是纵向展示的话就需要一个高度。因为当我们img元素渲染后如果没有指定高度它会默认为0此时还没有任何资源进行加载,那么所有的img元素都将会在可视区域内,那么他的isIntersecting都将会为true从而会加载所有资源,这样就无法实现懒加载的效果了,所以如果我们的图片都是一样大的我们可以指定好宽高,或者我们在给根元素指定一个特定的高度,然后按照我们需要在可视范围内想要展示图片数量,给每个img指定需要的高度,或者min-height让它把img元素撑开,这也就可以实现我们要的效果了。

这里我们因为定义的ul元素为1000px但是我们给img设置的min-height是900px,所以我们的img元素会有两个显示在当前可视区域内,由于我们设置的阈值为0所以在交叉边界为0的时候就调用回调函数加载资源,所以这里我们会加载两个图片资源。

当我们进行往下滑动的时候会进行图片的懒加载效果。

当然对于IntersectionObserver 还是一个较新的概念,所以可能对于相关的浏览器还是会有不兼容的。

我们可以参考下面的图片。

 

如果大家有想了解更多关于IntersectionObserver API的可以参考以下资源

https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver 

http://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IntersectionObserver实现图片懒加载(超详细!) 的相关文章

随机推荐

  • 2020-2021前端面试题合集,结果蒙了

    正文 介绍下半连接队列 服务器第一次接收到客户端的SYN后 会处于SYN REVD阶段 此时双方还没有建立完全的连接 服务器会把此种状态下请求连接放在一个队列里 我们把这种队列称为半连接队列 已经完成三次握手并建立连接 就叫全连接队列 ht
  • 对顺序表中元素从小到大排序的算法

    编写一个对顺序表中元素从小到大排序的算法 函数接口如下 初始条件 线性表L已经存在 且元素个数大于1 操作结果 将L中的元素从小到大排序 Status ListSort Sq SqList L 然后 在main函数中调用ListSort S
  • 两个变量进行值交换的三种方式

    在很多应用场景中我们需要将两个变量的值进行交换 在这里总结了3种方式以及它们的利弊 第一种 可以定义一个额外的变量用于进行数值交换 这是种最普通但实用性又很强的方法 int a 1 int b 2 int c a c 1 a b a 2 b
  • IOC控制反转

    IOC控制反转 核心思想 控制反转思想的核心就是把对象的控制权的 反转 对象的控制权包括对象的创建 管理 调用等 在对象的生命周期的各个阶段进行相应的管理 由编码人员交还给 程序本身 去管理 这屏蔽了对象创建和管理等过程 使得程序员可以将精
  • 刷脸支付带给人们真切的便捷和科技感

    刷脸支付异军突起的背后 是国内人脸识别功能等人工智能新技术与完备的硬件基础 通讯基础和数据基础共同作用的结果 随着今年5G的大规模商用 5G必然为其提供更多应用可能性 让刷脸支付与不同平台 企业 场景中的协作创新更加完备 可以预见 当刷脸支
  • 嵌入式开发人员-经历汇总

    目录 1 迷茫与前行 2 嵌入式到底该怎么学 2 1 单片机开发 2 2 Linux应用开发 3 嵌入式技术学习路线分享 4 单片机实习经历 2021年秋招记录 怀科同学 申明本文旨在为嵌入式工作提供入门建议 搬运总结 也会有自己的经验总结
  • 图论-最短路问题

    首先明确一个代码实现时候的问题 为什么使用0x3f3f3f3f而不是0x7f7f7f7f来表示无穷大INF 虽然0x7f7f7f7f确实更大而且符号位是0 但是在最短路算法中 经常出现形如min a a b 的表达式 如果此时a与b都是IN
  • AI焦虑潮下,打工人的抵抗、转向、破局

    一股 AI让人下岗 的焦虑 正在蔓延 蔓延到了 这里 不同于区块链 元宇宙和web3 2023年的这股AI浪潮真正席卷了所有人 在大厂 大佬和投资人们为船票激烈角逐的同时 Midjouney ChatGPT Notion AI等工具的惊人效
  • 闲鱼副业是什么?闲鱼副业应该怎么做?

    闲鱼副业是什么 闲鱼副业应该怎么做 有人会问 闲鱼现在还能做吗 还能赚钱吗 对于这样的问题 我只想说 其实再不好的行业 都有赚钱的牛人 再赚钱的领域 同样也有挣不到钱的人 所以 对于赚钱 有一句话是这样说的 没有不赚钱的项目 只有不会赚钱的
  • GPT专业应用:撰写工作简报

    图片由Lexica 生成 输入 Workers working overtime 工作简报 作为一种了解情况 沟通信息的有效手段 能使上级机关和领导及时了解 掌握所属部门的政治学习 军事训练 行政管理等方面的最新情况 同时 能和同级单位 部
  • FLEX & BISON 联合使用

    flex是词法分析器 bison是语法分析器 基本原理就是flex解析出token后 让bison来使用 实际上 一般是先编写bison脚本 里面的token就是一个定义 没有实现 里面的yylex也是没有实现 只有定义 为什么先做biso
  • 路由(route) 交换机(switch)简介

    路由 route 1 数据包从源地址到目的地址所经过的路径 由一系列路由节点组成 2 某个路由节点为数据包选择投递方向的选路过程 它是连接因特网中各局域网 广域网的设备 一 工作原理 工作于OSI七层协议中的第三层 接收来自一个网络接口的数
  • 租赁行业如何将电子合同活用起来?

    在租赁行业 采取传统纸质合同签署租赁类合同 需要相关人员全部在场签订 效率低下 随着互联网行业的发展 租房 租车等各种租赁类业务逐渐迁移到了线上 互联网租赁平台也因此应运而生 但也带来了各种问题 身份核实困难 中介越过平台做私单 诈骗租赁物
  • 线性代数 --- LU分解(Gauss消元法的矩阵表示)

    Gauss消元法等价于把系数矩阵A分解成两个三角矩阵L和U的乘法 首先 LU分解实际上就是用矩阵的形式来记录的高斯消元的过程 其中 对矩阵A进行高斯消元后的结果为矩阵U 是LU分解后的两个三角矩阵中其中之一 U是一个上三角矩阵 U就是上三角
  • elasticsearch 5.x删除index/type

    elasticsearch 5 x删除index 在head插件中执行 DELETE ip port index 看到 acknowledge true 即为成功 elasticsearch 5 x删除type 在kibana界面 dev
  • java 参数明明名字都是对的为什么值传不过来

    java 参数明明名字都是对的为什么值传不过来 那是因为值的类型不一样 导致匹配不上 一个是long 一个是string
  • C++数据结构笔记(3)线性表的链式存储底层实现

    本系列的帖子并不包含全部的基础知识 只挑一部分最核心的知识点总结 着重于具体的实现细节而并非理论的知识点总结 大家按需阅读学习 链表的核心概念总结如下 1 链式存储不需要连续的内存空间 2 链表由一系列的结点组成 每个节点包含两个域 分别是
  • Unity获得当前场景所有物体

    前言 1 GameObject FindObjectsOfType typeof GameObject 只能获得所有active物体 2 GameObject FindObjectsOfTypeAll该方法已过时 解决方案 可以使用Reso
  • 定义一个Student类,成员变量有姓名、年龄;用数组存5个学生对象,并输出

    public class Student String name int age public Student String name int age this name name this age age public class tex
  • IntersectionObserver实现图片懒加载(超详细!)

    关于IntersectionObserver 官方上说明是提供了一种异步观察目标元素与其祖先元素或顶级文档视窗 viewport 交叉状态的方法 祖先元素与视窗 viewport 被称为根 root 具体的内容可以参考官网解释 https