前端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.pswp.cn/bicheng/18447.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18447.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18447.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

yolov10 使用自己的數據集訓練目標檢測模型

1 環境配置(使用anaconda) conda create -n yolov10 python=3.9 //創建虛擬環境 conda activate yolov10 //激活虛擬環境 pip install -r requirements.txt //執行yolov10 路徑下requirements.txt 安裝依賴 pip install -e .2.數據集制作 使用lableImage制作數據集(win版…

華為云Astro Zero低代碼平臺案例:小、輕、快、準助力銷售作戰數字化經營

客戶背景&#xff1a; 隨著業務的不斷擴展&#xff0c;華為云某一線作戰團隊發現&#xff0c;原本基于線上Excel的項目跟蹤方式面臨新的挑戰&#xff1a;多區域、多場景下的業務管理越來越復雜&#xff0c;項目管道存在多種不可控因素&#xff0c;客戶關系、進展跟蹤同步不及時…

【Qt秘籍】[003]-Qt環境變量配置-磨刀不誤砍柴工

一、為什么要設置環境變量 &#xff1f;[原因] 配置PATH環境變量的主要用處在于讓操作系統能夠識別并執行不在當前工作目錄下的可執行文件。具體來說&#xff0c;它的作用包括&#xff1a; 命令執行便捷性&#xff1a;當你在命令行輸入一個命令&#xff08;如java, python或np…

【Unity程序】Unity游戲開發中常用的設計模式【一】

&#x1f468;?&#x1f4bb;個人主頁&#xff1a;元宇宙-秩沅 &#x1f468;?&#x1f4bb; hallo 歡迎 點贊&#x1f44d; 收藏? 留言&#x1f4dd; 加關注?! &#x1f468;?&#x1f4bb; 本文由 秩沅 原創 &#x1f468;?&#x1f4bb; 收錄于專欄&#xff1a;Uni…

【C語言習題】26.字符逆序

文章目錄 1.描述2.解題思路3.具體代碼 1.描述 輸入描述: 將一個字符串str的內容顛倒過來&#xff0c;并輸出。可以有空格 數據范圍&#xff1a;1≤&#x1d459;&#x1d452;&#x1d45b;(&#x1d460;&#x1d461;&#x1d45f;)≤10000 1≤len(str)≤10000 輸出描述&…

Android基礎-數據庫

在Android系統中&#xff0c;數據庫扮演著至關重要的角色&#xff0c;它負責存儲、管理和檢索應用程序所需的數據。隨著移動應用的日益復雜和功能的不斷增加&#xff0c;對數據庫的需求也日益提高。在Android中&#xff0c;有多種數據庫管理系統和工具可供選擇&#xff0c;其中…

NDIS協議驅動(四)

NDIS 定義對象標識符 (OID) 值&#xff0c;以標識適配器參數&#xff0c;其中包括設備特征、可配置設置和統計信息等操作參數。 協議驅動程序可以查詢或設置基礎驅動程序的操作參數。 NDIS 還為 NDIS 6.1 及更高版本的協議驅動程序提供直接 OID 請求接口。 直接 OID 請求路徑支…

利用EasyCVR視頻智能監控技術,構建智慧化考場監管體系

隨著科技的進步&#xff0c;視頻監控在各個領域的應用越來越廣泛&#xff0c;其中在考場中的應用尤為顯著。視頻監控不僅能夠提高考場的監管水平&#xff0c;確保考試的公平、公正和公開&#xff0c;還能有效預防和打擊作弊行為&#xff0c;為考生營造一個良好的考試環境。 傳…

前后端分離跨域問題解決方案

Vue和SpringBoot的跨域問題的4中解決方案 跨域問題產生的原因&#xff1a;瀏覽器的保護機制&#xff0c;同源策略協議&#xff0c;域名&#xff0c;端口&#xff1b;三個中有一個不同就會產生跨域問題 解決方案&#xff08;后端&#xff09;&#xff1a; 1.CrossOrigin注解&…

界面控件DevExtreme v23.2亮點 - 標簽、表單、編輯器功能升級

DevExtreme擁有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用現代Web開發堆棧&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;構建交互式的Web應用程序。從Angular和Reac&#xff0c…

腦圖工具 在學習系統架構中的使用

系統&#xff0c;有人把它比作一個黑盒&#xff0c;有人比作一個樹洞。呃&#xff0c;其實二者都隱含的表達了一個意思&#xff0c;盤根錯節&#xff0c;一言難盡&#xff0c;欲說還休&#xff0c;說了又像是隔靴搔癢&#xff0c;感覺沒說透。 學習&#xff0c;理解和展示一個…

計算機組成原理----移碼

在網上搜索移碼是什么,大概率會搜到一個結論:移碼是補碼符號位取反,可是真的是這樣嗎? 傳統的有符號整數是將二進制數的首位作為符號位,0表示正數,1表示負數。 但在移碼中,我們不再使用單獨的符號位來表示正負。而是通過一個固定的偏置量來將所有可能的指數值映射到一個無符…

力扣每日一題 5/28

題目&#xff1a;2951-找出峰值 給你一個下標從 0 開始的數組 mountain 。你的任務是找出數組 mountain 中的所有 峰值。 以數組形式返回給定數組中 峰值 的下標&#xff0c;順序不限 。 注意&#xff1a; 峰值 是指一個嚴格大于其相鄰元素的元素。數組的第一個和最后一個元…

C語言.順序表.通訊錄

基于順序表示實現通訊錄 1.通訊錄項目的功能要求2.代碼實現3.頭文件處理4.通訊錄的具體實現4.1通訊錄的初始化與銷毀4.1.1通訊錄的初始化4.1.2通訊錄的初始化銷毀 4.2通訊錄的添加與刪除數據4.2.1通訊錄的添加數據4.2.1通訊錄的刪除數據 4.3通訊錄的修改4.4通訊錄的查找4.5通訊…

熟悉電腦快捷鍵(包含部分VS)

有很多不太電腦的小白&#xff0c;這里給大家一些常用快捷鍵&#xff0c;希望幫助到大家學習~ ctrl c 復制&#xff08;保留原內容&#xff09; ctrl v 粘貼 ctrl x 剪切&#xff08;跟復制不一樣的地方在于原內容清空&#xff09; ctrl z …

【python】OpenCV—Tracking(10.2)

文章目錄 BackgroundSubtractorcreateBackgroundSubtractorMOG2createBackgroundSubtractorKNN BackgroundSubtractor Opencv 有三種背景分割器 K-Nearest&#xff1a;KNN Mixture of Gaussian&#xff08;MOG2&#xff09; Geometric Multigid&#xff08;GMG&#xff09; …

AURIX TC3xx單片機介紹-啟動過程介紹2

AURIX TC377,TC387,TC397用戶啟動程序流程 用戶啟動程序是在Boot Firmware之后運行的程序(即用戶程序里的第一級Boot Loader,類似Linux的Uboot),初始化過程是CPU0完成的。用戶可以根據不同的復位事件來選擇不同的執行路徑。 AURITX 2代芯片的主要啟動過程如下(該階段只…

WebGL學習(一)渲染關系

學習webgl 開發理解渲染關系是必須的&#xff0c;也非常重要&#xff0c;很多人忽視了這個過程。 我這里先簡單寫一下&#xff0c;后面盡量用通俗易懂的方式&#xff0c;舉例講解。 WebGL&#xff0c;全稱Web Graphics Library&#xff0c;是一種在網頁上渲染3D圖形的技術。它…

C++模板元編程--函數萃取

在C中&#xff0c;std::declval是一個非常有用的模板函數&#xff0c;它是標準庫<utility>頭文件的一部分。它的主要作用是在不創建對象的情況下&#xff0c;獲取該類型的引用&#xff0c;從而允許在編譯時表達式中使用該類型的成員函數或成員變量&#xff0c;即使沒有默…

python中的-1是什么意思

python中的-1是什么意思&#xff1f; -1指的是索引&#xff0c;即列表的最后一個元素。 比如你輸入一個列表&#xff1a; a &#xff1d; [1,2,3,4,5,6,7] a[-1]就代表索引該列表最后一個值&#xff0c;你可以 b a[-1] print(b) 結果如下&#xff1a; 7 索引從左往右是…