IntersectionObserver用法

news2025/2/21 21:30:48

IntersectionObserver用法

  • 1.什么是IntersectionObserver?
  • 2.使用
    • 2.1 创建观察对象
    • 2.2 观察指定DOM对象
    • 2.3 参数详解
      • (1)callback参数
      • (2)options 配置参数
  • 3.应用
    • 3.1 Dom进入页面的加载动画
    • 3.2 图片的懒加载

1.什么是IntersectionObserver?

IntersectionObserver接口,提供了一种异步观察目标元素与其祖先元素或顶级文档视窗交叉状态的方法。可能很多人听不懂啥意思,那也没关系,看下面的示例能理解就可以了。

2.使用

2.1 创建观察对象

let  observer = new IntersectionObserver(callback, options)

2.2 观察指定DOM对象

observer.observe(DOM元素)

observer观察者对象在观察元素是否进入视口、祖先元素的时候,不管元素是否进入,都会触发观察者对象的回调函数!

	let box = document.querySelector('.box')
	let observer = new IntersectionObserver(function(entries){
		console.log(entries)
	})
	observer.observe(box)

可以发现,程序一开始会默认执行一次输出,因为box盒子默认就在视口当中,所以会触发一次;

2.3 参数详解

如下是IntersectionObserver的使用格式:

let  observer = new IntersectionObserver(function(entries,observer){
		//回回调函数接受两个参数,第二个可以不写,因为用处不大
}, options)

(1)callback参数

回调函数接受两个参数,分别是:

  • 所有被监听的dom对象集合,一般用 entries 表示;
  • 以及观察者对象,一般用observer表示,可写可不写。

在entries集合中的每一个元素都是被监听的对象,被监听的对象上有一些属性。可以打印一下看看:
在这里插入图片描述
由上可知IntersectionObserverEntry对象格式如下:

{
  time: 3893.92,
  rootBounds: ClientRect {
    bottom: 920,
    height: 1024,
    left: 0,
    right: 1024,
    top: 0,
    width: 920
  },
  boundingClientRect: ClientRect {
     // ...
  },
  intersectionRect: ClientRect {
    // ...
  },
  intersectionRatio: 0.54,
  isIntersecting:false,
  isVisible:false,
  target: element
}

其中比较常用的属性是:

  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒
  • target:被观察的目标元素,是一个 DOM 节点对象
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
  • boundingClientRect:目标元素的矩形区域的信息
  • isIntersecting:true表示当前元素进入视口,false表示当前元素离开视口
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
  • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0

注意:操作entries集合中的Dom对象,记得加索引!

let box = document.querySelector('.box');
let observer = new IntersectionObserver(function(entries){
	   	console.log( entries[0].isIntersecting );
})
observer.observe(box)

(2)options 配置参数

options是一个对象,有三个参数:
第一个参数: root: 祖先级对象 | null
root属性的值可以是一个祖先级对象,这时,主要的是针对局部的滚动效果。当root属性不写,或者值为null时,表示的是监听DOM元素与当前视口的交叉关系!

第二个参数:rootMargin: 视口的外延值相当于扩大视口的范围:
rootMargin属性是规定视口的外延值,相当于扩大了视口的范围,用于提早触发观察者回调函数。
如下图:
在这里插入图片描述

第三个参数:threshold:0-1 表示当被观察者进入视口百分之多少时触发观察者:
threshold默认值是0,表示刚进入时就触发观察者的回调函数,完全离开时,再触发观察的回调;当threshold的值是1,表示当被监听元素完全进入视图在触发观察者的回调函数,当元素刚离开时,再触发观察的回调。

如果把threshold设为0-1中间的某值:
在这里插入图片描述

3.应用

3.1 Dom进入页面的加载动画

如下图:
在这里插入图片描述
代码如下:

<style>
	.show{
         transform: translateY(0) scale(1);
         opacity: 1;
     }
     .hide{
         transform: translateY(100%) scale(0);
         opacity: 0;
     }
     //css样式可自行决定,这里虽然没写,但别忘了添加transtion过渡属性,让动画更加平滑
<style>
<body>
    <ul class="list">
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</body>
<script>
    let lis = document.querySelectorAll(".list li");
    let observer = new IntersectionObserver(function(entries){
    	// 2 这里会接收到所有被观察的 dom 对象
        for(let i = 0; i < entries.length; i++ ){
        	//遍历所有被观察对象,判断其是否出现在视口
            if( entries[i].isIntersecting ){
            	//为true则表示出现在视口,然后为其添加出现样式
                entries[i].target.classList.remove('hide');
                entries[i].target.classList.add('show')
            }
            else{
               //为flase则表示消失在视口,然后为其添加消失样式
                if( entries[i].boundingClientRect.top > 0 ){
                	//这里是判断li是否是往下消失
                    entries[i].target.classList.remove('show');
                    entries[i].target.classList.add('hide')
                }
            }
        }
    });
    for(let i = 0; i < lis.length; i++ ){
        observer.observe(lis[i])
        // 1 给所有li添加监听观察
    }
</script>

核心逻辑是:通过css给指定元素添加过渡属性,然后使用观察对象监听每个元素,给默认在视口中的元素做最终值的处理,给不在视口中的元素做初始值的处理。那么当元素进入视口的时候,初始值 -> 最终值 就会应用过渡动画!

3.2 图片的懒加载

如下图:
在这里插入图片描述
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        ul{
            list-style: none;
        }
        .box{
            width: 80%;
            margin: 0 auto;
            display: flex;
            flex-wrap: wrap;
        }
        .item{
            width: calc( 33.33% - 20px );
            margin: 10px;
            min-height: 200px;
        }
        .item img{
            width: 100%;
        }
    </style>
</head>
<body>
    <div class="box">
        <!-- <div class="item">
            <img src="./img/Empty.svg" alt="">
        </div> -->
    </div>
</body>
<script>
	//先做一个数组,用来装图片的网络地址
    let imgList = [
		{
			default:'./img/Empty.svg', //这是默认生效的图片,你可以改成自己的
			url:'https://images.pexels.com/photos/23719800/pexels-photo-23719800.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/20569931/pexels-photo-20569931.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/23105903/pexels-photo-23105903.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		}
		,
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/22816073/pexels-photo-22816073.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/18197764/pexels-photo-18197764.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/24031902/pexels-photo-24031902.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		}
		,
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/23914518/pexels-photo-23914518.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/16118941/pexels-photo-16118941.jpeg?auto=compress&cs=tinysrgb&w=800&lazy=load'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/22937531/pexels-photo-22937531.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/21915597/pexels-photo-21915597.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/16703290/pexels-photo-16703290.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		}
		,
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/13298586/pexels-photo-13298586.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/18109714/pexels-photo-18109714.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/22670156/pexels-photo-22670156.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		}
		,
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/21852583/pexels-photo-21852583.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/21367366/pexels-photo-21367366.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/17102067/pexels-photo-17102067.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/24038436/pexels-photo-24038436.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		}
		,
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/19473669/pexels-photo-19473669.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/20470948/pexels-photo-20470948.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/22469105/pexels-photo-22469105.jpeg?auto=compress&cs=tinysrgb&w=800&lazy=load'
		}
		,
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/13743557/pexels-photo-13743557.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'
		},
		{
			default:'./img/Empty.svg',
			url:'https://images.pexels.com/photos/23230661/pexels-photo-23230661.jpeg?auto=compress&cs=tinysrgb&w=800&lazy=load'
		},
	]

    let box = document.querySelector('.box');
	
	//渲染页面结构的工具函数,用来遍历list,然后渲染成dom结构到页面
    function initImg(list){
        for( let i = 0; i < list.length; i++ ){
            let div = document.createElement('div');
            div.className = 'item';
            let img = document.createElement('img');
            img.src = list[i].default;
            img.dataset.url= list[i].url;
            div.appendChild(img);
            box.appendChild(div);
        }
    }
    initImg(imgList);//先调用一次工具函数
    window.onload = function(){
    	//这里要等页面加载完毕,也就是默认图片加载完毕后,再执行之后的逻辑
        let items =  document.querySelectorAll('.item');
        Observer(items);//调用观察者工具函数,给其传要观察的Dom对象
    }
    //观察者工具函数
    function Observer(list){
        let observer = new IntersectionObserver(function(entries){
            for(let n = 0; n < entries.length; n++ ){
                if( entries[n].isIntersecting && entries[n].target.children[0].src.includes( "img/Empty.svg" ) ){
                    entries[n].target.children[0].src = entries[n].target.children[0].dataset.url;
                }
            }
        })
        for(let i = 0; i < list.length; i++ ){
            observer.observe(list[i])
        }
    }
</script>
</html>

核心逻辑是:通过src加载一张本地的默认图片,然后通过data-url引入真实的地址。当图片进入视口以后,使用data-url的图片地址,替换src的图片地址,实现图片只有进入视口时才加载的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2302122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

R语言NIMBLE、Stan和INLA贝叶斯平滑及条件空间模型死亡率数据分析:提升疾病风险估计准确性...

全文链接&#xff1a;https://tecdat.cn/?p40365 在环境流行病学研究中&#xff0c;理解空间数据的特性以及如何通过合适的模型分析疾病的空间分布是至关重要的。本文主要介绍了不同类型的空间数据、空间格点过程的理论&#xff0c;并引入了疾病映射以及对空间风险进行平滑处理…

DeepSeek - R1:模型架构深度解析

DeepSeek - R1&#xff1a;模型架构深度解析 引言 本文将深入探索DeepSeek - R1模型架构。将从输入到输出追踪DeepSeek - R1模型&#xff0c;找出架构中的新发展和关键部分。DeepSeek - R1基于DeepSeek - V3 - Base模型架构&#xff0c;本文旨在涵盖其设计的所有重要方面。 …

火绒终端安全管理系统V2.0【系统防御功能】

火绒企业版V2.0系统防御功能包含系统加固、应用加固、软件安装拦截、摄像头保护和浏览器保护。火绒终端安全管理软件V2.0守护企业用户终端安全。 系统防御 1. 系统加固 系统加固功能根据火绒提供的安全加固策略&#xff0c;当程序对特定系统资源操作时提醒用户可能存在的安…

Word中接入大模型教程

前言 为什么要在word中接入大模型呢&#xff1f; 个人觉得最大的意义就是不用来回切换与复制粘贴了吧。 今天分享一下昨天实践的在word中接入大模型的教程。 在word中接入大模型最简单的方式就是使用vba。 vba代码要做的事&#xff0c;拆分一下就是&#xff1a; 获取用户…

【git-hub项目:YOLOs-CPP】本地实现04:项目简化

项目跑通之后,我们常常还需要对我们没有用到的任何内容进行删除,以简化项目体积,也便于我们阅读和后续部署。如何实现呢?本篇博客教会大家实现! 项目一键下载【⬇️⬇️⬇️】: 精简后:【GitHub跑通项目:YOLOs-CPP】+【计算机视觉】+【YOLOv11模型】+【windows+Cpp+ONN…

CTF 代码学习日记 PHP

基础 2字符串连接可以使用点号&#xff08;.&#xff09; 3.$_&#xff1a;在 PHP 中&#xff0c;以$_开头的变量&#xff08;如$_GET、$_POST、$_COOKIE等&#xff09;是超级全局变量。超级全局变量的特点是它们在 PHP 脚本的任何地方&#xff08;包括函数内部、类内部等&am…

观察者模式说明(C语言版本)

观察者模式主要是为了实现一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时&#xff0c;会通知所有观察者对象&#xff0c;使它们能够自动更新自己。下面使用C语言实现了一个具体的应用示例&#xff0c;有需要的可以参考…

【从0做项目】Java搜索引擎(6) 正则表达式鲨疯了优化正文解析

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 文章导读 零&#xff1a;项目结果展示 一&#xff1a;导读&知识点回顾 二&#xff1a;遗留问题 …

【论文技巧】Mermaid VSCode插件制作流程图保存方法

插流程图快点 利用Mermaid Preview插件自带功能 如果你的VSCode安装了支持导出图片的Mermaid预览插件&#xff08;如 Mermaid Markdown Syntax Highlighting 等&#xff09;&#xff0c;可以按以下步骤进行&#xff1a; 打开Mermaid代码文件&#xff1a;在VSCode中打开包含M…

【DeepSeek】如何将DeepSeek部署到本地?如何给本地 LLM 提供UI界面?CherryStudio 的使用

注&#xff1a;如果下面的所有操作&#xff0c;需要访问到 Github&#xff0c;可以先看这篇文章&#xff0c;了解如何流畅连接 Github 【Github】如何流畅链接Github.com-CSDN博客 一、下载 Ollama 1、访问网址 Ollama&#xff0c;点击下载 Ollama 到本地 选择自己计算机的系统…

mac开发环境配置笔记

1. 终端配置 参考&#xff1a; Mac终端配置笔记-CSDN博客 2. 下载JDK 到 oracle官网 下载jdk: oracle官网 :Java Downloads | Oraclemac的芯片为Intel系列下载 x64版本的jdk&#xff1b;为Apple Mx系列使用 Arm64版本&#xff1b;oracle官网下载时报错&#xff1a;400 Bad R…

交换机基本命令

目录 一、华为交换机基本命令 1、VRP视图层 2、命令帮助 3、配置设备名称 4、命令等级&#xff08;一般生产过程没有下面的详细&#xff09; 5、用户界面 6、配置Console认证 控制台接口&#xff08;Console&#xff09; 配置步骤示例 7、配置VTY登录&#xff08;本文…

PHP图书借阅小程序源码

&#x1f4da; 图书借阅小程序&#xff1a;一键开启智慧阅读新篇章 &#x1f31f; 这是一款由ThinkPHP与UniApp两大技术巨擘强强联手精心打造的图书借阅微信小程序&#xff0c;它犹如一座随身携带的移动图书馆&#xff0c;让您无论身处何地都能轻松畅游知识的海洋。创新的多书…

UE 播放视频

一.UI播放视频 1.导入视频文件至工程文件夹 2.文件夹内右健选择Media -> File Meida Source创建testFileMeidaSource文件。 编辑FilePath为当前视频 3.右键->Media->Media Player 创建testMediaPlayer文件 4.右键创建testMediaTexture。编辑MediaPlayer设置testMedia…

拦截器VS过滤器:Spring Boot中请求处理的艺术!

目录 一、拦截器&#xff08;Interceptor&#xff09;和过滤器&#xff08;Filter&#xff09;&#xff1a;都是“守门员”&#xff01;二、如何实现拦截器和过滤器&#xff1f;三、拦截器和过滤器的区别四、执行顺序五、真实的应用场景六、总结 &#x1f31f;如果喜欢作者的讲…

react实例与总结(二)

目录 一、脚手架基础语法(16~17) 1.1、hello react 1.2、组件样式隔离(样式模块化) 1.3、react插件 二、React Router v5 2.1、react-router-dom相关API 2.1.1、内置组件 2.1.1.1、BrowserRouter 2.1.1.2、HashRouter 2.1.1.3、Route 2.1.1.4、Redirect 2.1.1.5、L…

巧用GitHub的CICD功能免费打包部署前端项目

近年来&#xff0c;随着前端技术的发展&#xff0c;前端项目的构建和打包过程变得越来越复杂&#xff0c;占用的资源也越来越多。我有一台云服务器&#xff0c;原本打算使用Docker进行部署&#xff0c;以简化操作流程。然而&#xff0c;只要执行sudo docker-compose -f deploy/…

使用 DeepSeek 生成商城流程图

步骤 1.下载 mermaid 2.使用 DeepSeek 生成 mermaid 格式 3.复制内容到 4.保存备用。 结束。

VSCode自定义快捷键和添加自定义快捷键按键到状态栏

VSCode自定义快捷键和添加自定义快捷键按键到状态栏 &#x1f4c4;在VSCode中想实现快捷键方式执行某些指令操作&#xff0c;可以通过配置组合式的键盘按键映射来实现&#xff0c;另外一种方式就是将执行某些特定的指令嵌入在面板菜单上&#xff0c;在想要执行的时候&#xff0…

Ubuntu22.04 - gflags的安装和使用

目录 gflags 介绍gflags 安装gflags 使用 gflags 介绍 gflags 是Google 开发的一个开源库&#xff0c;用于 C应用程序中命令行参数的声明、定义和解析。gflags 库提供了一种简单的方式来添加、解析和文档化命令行标志(flags),使得程序可以根据不同的运行时配置进行调整。 它具…