当前位置: 首页 > news >正文

前端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的占位内容。

在这里插入图片描述

当滑动图片的位置的时候才加载出相对应的图片地址和对应的类名

在这里插入图片描述

http://www.lryc.cn/news/356660.html

相关文章:

  • C++迈向精通:vector复现与sort复现
  • 【头歌】计算机网络DHCP服务器配置第二关access口配置答案
  • Python机器学习 Tensorflow + keras 实现CNN
  • 基于事件的架构工作机制和相关产品
  • OSINT 与心理学:通过开源情报进行剖析和行为分析
  • yarn 设置淘宝镜像配置
  • debian 常用命令
  • 流水账(CPU设计实战)——lab3
  • k8s集群配置普通用户权限
  • clickhouse——clickhouse单节点部署及基础命令介绍
  • MATLAB基础应用精讲-【数模应用】价格敏感度PSM分析(附python代码实现)
  • 数据驱动的UI艺术:智能设计的视觉盛宴
  • 栈的特性及代码实现(C语言)
  • 防火墙如何端口映射?
  • 咖啡看书休闲时光404错误页面源码
  • 中央事件bus
  • 中国上市企业行业异质性数据分析
  • 【全开源】防伪溯源一体化管理系统源码(FastAdmin+ThinkPHP和Uniapp)
  • 鸿蒙ArkUI-X跨语言调用说明:【平台桥接(@arkui-x.bridge)】
  • ts面试题: 面试题2
  • .NET 某和OA办公系统全局绕过漏洞分析
  • Git-01
  • GitLab的原理及应用详解(七)
  • Vue中使用Vue-scroll做表格使得在x轴滑动
  • 【高频】从输入URL到页面展示到底发生了什么?
  • 【CSharp】ushort[]的IntPtr快速转换为ushort[]无符号短整型数组
  • 释放 OSINT 的力量:在线调查综合指南
  • 22.Volatile原理
  • Vue 3中的v-for指令使用详解
  • GB-T 43694-2024 网络安全技术 证书应用综合服务接口规范