前端API: IntersectionObserver的那一二三件事
IntersectionObserver 基础
IntersectionObserver 可以监听一个元素和可视区域相交部分的比例,然后在可视比例达到某个阈值的时候触发回调。比如可以用来处理图片的懒加载等等
首先我们来看下基本的格式:
const observer = new IntersectionObserver(callback, [options]);
相关的API属性和方法:
直接看他的Typescript结构吧
interface IntersectionObserver {// root 属性用来获取当前 intersectionObserver 实例的根元素readonly root: Element | Document | null;readonly rootMargin: string;readonly thresholds: ReadonlyArray<number>;disconnect(): void;observe(target: Element): void;takeRecords(): IntersectionObserverEntry[];unobserve(target: Element): void;
}
root
: 如果构造函数未传入 root
或其值为null
,则默认使用顶级当前文档的视口。
rootMargin
: 是 IntersectionObserver
构造函数的一个可选属性,它定义了一个矩形区域,用于扩展或缩小root
元素的可视区域,从而影响intersectionRatio
的计算
const observer = new IntersectionObserver(entries => {// 处理entries},{root: document.querySelector('#scrollArea'), // 根元素 || 顶级当前文档rootMargin: '50px 20px 30px 10px' // 上右下左}
);
thresholds
:,它定义了一个监听交叉变化时触发回调的阈值列表。这些阈值是介于0和1之间的数值,包括0和1,表示目标元素与根元素相交的比例。举个例子,当创建一个IntersectionObserver
实例时,你可以指定一个或多个阈值。例如,如果你想要在目标元素至少有25%、50%和75%可见时触发回调,你可以这样设置thresholds
const observer = new IntersectionObserver(entries => {// 处理entries},{thresholds: [0, 0.25, 0.5, 0.75, 1]}
);
disconnect
用于停止监听目标元素与根元素的交叉变化。当你不再需要观察元素的可见性变化时,可以调用disconnect
方法来停止IntersectionObserver
的所有活动。
调用disconnect
方法后,IntersectionObserver
将不再触发任何回调,即使目标元素的可见性发生变化。这意味着,你已经不再对目标元素的可见性感兴趣,或者你想要在组件卸载时清理资源。
// 创建一个IntersectionObserver实例
const observer = new IntersectionObserver(function(entries) {// 处理交叉变化entries.forEach(function(entry) {if (entry.isIntersecting) {console.log('元素现在可见');} else {console.log('元素不再可见');}});
});// 开始观察一个元素
const target = document.querySelector('#my-element');
observer.observe(target);// ...一段时间后...// 停止观察元素
observer.disconnect();
observer
: 用于开始监听一个目标元素与根元素的交叉变化。当你想要知道一个元素是否进入了视口(即用户的可见区域)时,你可以使用observe
方法来指定需要观察的元素
// 创建一个IntersectionObserver实例
const observer = new IntersectionObserver(function(entries) {// 处理交叉变化entries.forEach(function(entry) {if (entry.isIntersecting) {console.log('元素现在可见');} else {console.log('元素不再可见');}});
});// 获取要观察的元素
const target = document.querySelector('#my-element');// 开始观察元素
observer.observe(target);
takeRecords
:用于获取并清空IntersectionObserver
实例的记录队列。这个方法返回一个IntersectionObserverEntry
对象的数组,每个对象描述了目标元素的相交状态
unobserve
:用于停止监听特定目标元素与根元素的交叉变化。当你不再需要监听某个元素的可见性变化时,你可以使用unobserve
方法来停止对该元素的观察。
综合案例,实现图片的懒加载
下面的方法使用的react,可以做必要的安装哦!
下面是一个设置一个组件,看如下代码
/** @Date: 2024-05-28 09:59:48* @Description: 组件的设计*/
import { CSSProperties, FC, ReactNode, useEffect, useRef, useState } from "react";interface MyLazyloadProps {className?: string; /* className 和 style 是给外层 div 添加样式的 */style?: CSSProperties;placeholder?: ReactNode; /* 是占位的内容 */offset?: string | number; /* 是距离到可视区域多远就触发加载 */width?: number | string;height?: string | number;onContentVisible?: () => void; /* 进入可视化区域后所产生的回调 */children: ReactNode;
}const MyLazyload: FC<MyLazyloadProps> = (props) => {const { className = "", style, offset = 0, width, onContentVisible, placeholder, height, children } = props;const containerRef = useRef<HTMLDivElement>(null);const [visible, setVisible] = useState(false);const elementObserver = useRef<IntersectionObserver>();/* 关键函数去判断可视范围 */const lazyLoadHandler = (entries: IntersectionObserverEntry[]) => {const [entry] = entries;const { isIntersecting, intersectionRatio } = entry;if (intersectionRatio > 0) {const node = containerRef.current;console.log(node, entry, intersectionRatio);}if (isIntersecting) {setVisible(true);/* 可以通过这一层函数传递给外部,然后通过这个函数,可以在外部组件做相对应的处理等等 */onContentVisible?.();const node = containerRef.current;// 展示完成后及时的销毁if (node && node instanceof HTMLElement) {elementObserver.current?.unobserve(node);}}}useEffect(() => {const options = {/* 这边没有写root,则这边的根元素就是此文档的 containerRef *//* rootMargin 这边做了一次偏移处理 */rootMargin: typeof offset === 'number' ? `${offset}px` : offset || '0px',/* 设置 threshold 为 0 也就是一进入可视区域就触发 */threshold: 0,}elementObserver.current = new IntersectionObserver(lazyLoadHandler, options);const node = containerRef.current; // 拿到nodeif (node instanceof HTMLElement) {elementObserver.current.observe(node);}return () => {if (node && node instanceof HTMLElement) {elementObserver.current?.unobserve(node);}}}, []);const styles = { height, width, ...style };return (<div ref={containerRef} className={`${className}`} style={styles}>{visible ? children : placeholder}</div>);
};export default MyLazyload;
组件的调用:
/** @Date: 2024-05-27 11:21:07* @Description: 组件的调用*/
import { useState } from "react";
import img1 from "./素材1.png";
import img2 from "./扑克牌1.jpg";
import "./App.css";
// import LazyLoad from 'react-lazyload';
import LazyLoad from "./MyLazyLoad";function App() {const [isVisible, setIsVisible] = useState<boolean>(false);return (<div><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p><p>一一一一一一一一一一一一一一一一一一</p>{/* 这边增加一些类名可以做一些的动画 */}<LazyLoadclassName={isVisible ? "show" : "hide"}placeholder={<div>loading...</div>}onContentVisible={() => {console.log("comp visible");setIsVisible(true);}}>{/* <img src={img1}/> */}</LazyLoad><LazyLoadplaceholder={<div>loading...</div>}onContentVisible={() => {console.log("img visible");}}><img src={img2} /></LazyLoad></div>);
}export default App;
我们看最后的效果:
当刚进入页面的时候,我们下面的元素都处于 loading中,也是上面的placeholder的占位内容。
当滑动图片的位置的时候才加载出相对应的图片地址和对应的类名
相关文章:

前端API: IntersectionObserver的那一二三件事
IntersectionObserver 基础 IntersectionObserver 可以监听一个元素和可视区域相交部分的比例,然后在可视比例达到某个阈值的时候触发回调。比如可以用来处理图片的懒加载等等 首先我们来看下基本的格式: const observer new IntersectionObserver(c…...
C++迈向精通:vector复现与sort复现
vector复现 思考过程 对于vector考虑如下几点: 底层数据结构算法实现方式对外表现形式 这里底层的数据结构采用了顺序表,当然,原版STL中的vector也是采用的顺序表。 算法实现的方式放在代码中去设计 对外表现形式是数组,因此需…...

【头歌】计算机网络DHCP服务器配置第二关access口配置答案
头歌计算机网络DHCP服务器配置第二关access口配置操作步骤 任务描述 本关任务:创建 vlan ,并且将与 pc 机相连接口划分 vlan 。 操作要求 在第一关的拓扑图的基础上,配置交换机,具体要求如下: 1、在特权模式下进入 vla…...

Python机器学习 Tensorflow + keras 实现CNN
一、实验目的 1. 了解SkLearn Tensorlow使用方法 2. 了解SkLearn keras使用方法 二、实验工具: 1. SkLearn 三、实验内容 (贴上源码及结果) 使用Tensorflow对半环形数据集分 #encoding:utf-8import numpy as npfrom sklearn.datasets i…...
基于事件的架构工作机制和相关产品
基于事件的架构 基于事件的架构可否这样理解,每个事件相当于传统API的一次函数调用请求,比如Add(123,456)。区别在于,基于事件的架构只是把这个请求发出,并不急于得到结果,而是等合适的子系统处理完这个请求ÿ…...

OSINT 与心理学:通过开源情报进行剖析和行为分析
在不断发展的心理学领域,人们越来越认识到通过应用开源情报 (OSINT) 方法取得进步的潜力。OSINT 主要以其在安全和情报领域的应用而闻名,并且越来越多地展示其在心理分析和行为分析方面的潜力。本文探讨了 OSINT 和心理学的迷人交叉点,研究如…...
yarn 设置淘宝镜像配置
为了提升在中国大陆地区的下载速度,你可以将Yarn的包仓库配置为淘宝镜像。最新的推荐做法是使用npmmirror.com作为镜像源,替代旧的npm.taobao.org。以下是设置Yarn使用淘宝镜像(npmmirror.com)的步骤: 查询当前镜像配置…...
debian 常用命令
Debian 是一个广泛使用的 Linux 发行版,这里列出了一些常用的 Debian 命令,适用于系统管理和日常使用: ### 文件与目录操作 1. **ls** - 列出目录内容: bash ls ls -l # 长格式显示 ls -a # 显示所有文件ÿ…...

流水账(CPU设计实战)——lab3
Lab3 Rewrite V1.0 版本控制 版本描述V0V1.0相对V0变化: 修改了文件名,各阶段以_stage结尾(因为if是关键词,所以module名不能叫if,遂改为if_stage,为了统一命名,将所有module后缀加上_stage&a…...
k8s集群配置普通用户权限
集群管理员:负责管理 Kubernetes 集群的用户,拥有最高权限,可以对集群中的资源进行任何操作。 开发者:在 Kubernetes 集群中部署和管理自己的应用,可能有限制的权限,仅能管理特定的命名空间或资源。 第三…...

clickhouse——clickhouse单节点部署及基础命令介绍
clickhouse支持运行在主流的64位CPU架构的linux操作系统之上,可以通过源码编译,预编译压缩包,docker镜像和rpm等多种方式进行安装。 一、单节点部署 1、安装curl工具 yum install -y curl 2、添加clickhouse的yum镜像 curl -s https://pack…...
MATLAB基础应用精讲-【数模应用】价格敏感度PSM分析(附python代码实现)
目录 前言 算法原理 什么是价格敏感度分析? 原理 示例 PSM用途...

数据驱动的UI艺术:智能设计的视觉盛宴
数据驱动的UI艺术:智能设计的视觉盛宴 引言 在当今这个数据泛滥的时代,大数据不仅仅是一种技术手段,它更是一种艺术形式。当大数据遇上UI设计,两者的结合便催生了一种全新的艺术形式——数据驱动的UI艺术。本文将探讨如何将数据…...

栈的特性及代码实现(C语言)
目录 栈的定义 栈的结构选取 链式储存结构和顺序栈储存结构的差异 栈的代码实现 "stack.h" "stack.c" 总结 栈的定义 栈:栈是限定仅在表尾进行插入和删除操作的线性表。 我们把运行插入的和删除的一段叫做栈顶(TOPÿ…...

防火墙如何端口映射?
防火墙端口映射(Firewall Port Mapping)是一种网络技术,通过对防火墙配置进行调整,允许外部网络用户访问内部网络中的指定端口。该技术使得外部用户可以通过公共网络访问内部网络中的特定服务或应用程序,从而实现远程访…...

咖啡看书休闲时光404错误页面源码
源码介绍 咖啡看书休闲时光404错误页面源码,源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面 源码效果 源码下载 咖啡看书…...
中央事件bus
中央事件bus的使用 使用场景:当需要传递给多个组件的时候例如父组件->子组件->孙组件,甚至还得传递到更深的组件的时候中央事件就起到了作用,不需要一直传递。bus其实就是一个发布订阅模式,利用vue的自定义事件机制 // 事…...

中国上市企业行业异质性数据分析
数据简介:企业行业异质性数据是指不同行业的企业在运营、管理、财务等方面的差异性数据。这些数据可以反映不同行业企业的特点、优势和劣势,以及行业间的异质性对企业经营和投资的影响。通过对企业行业异质性数据的分析,投资者可以更好地了解…...

【全开源】防伪溯源一体化管理系统源码(FastAdmin+ThinkPHP和Uniapp)
一款基于FastAdminThinkPHP和Uniapp进行开发的多平台(微信小程序、H5网页)溯源、防伪、管理一体化独立系统,拥有强大的防伪码和溯源码双码生成功能(内置多种生成规则)、批量大量导出防伪和溯源码码数据、支持代理商管理…...

鸿蒙ArkUI-X跨语言调用说明:【平台桥接(@arkui-x.bridge)】
平台桥接(arkui-x.bridge) 简介 平台桥接用于客户端(ArkUI)和平台(Android或iOS)之间传递消息,即用于ArkUI与平台双向数据传递、ArkUI侧调用平台的方法、平台调用ArkUI侧的方法。 以Android平台为例,Ark…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
Python实现简单音频数据压缩与解压算法
Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中,压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言,提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...

uni-app学习笔记三十五--扩展组件的安装和使用
由于内置组件不能满足日常开发需要,uniapp官方也提供了众多的扩展组件供我们使用。由于不是内置组件,需要安装才能使用。 一、安装扩展插件 安装方法: 1.访问uniapp官方文档组件部分:组件使用的入门教程 | uni-app官网 点击左侧…...