js 監聽元素是否出現在可視區域--IntersectionObserver

觀察者模式監聽判斷dom元素是否在可視區域內
本項目是使用vue3的寫法。

1.IntersectionObserver

IntersectionObserver可以用來自動監聽元素是否進入了設備的可視區域之內,而不需要頻繁的計算來做這個判斷。由于可見(visible)的本質是,目標元素與視口產生一個交叉區,所以這個 API 叫做"交叉觀察器"

const observer = new IntersectionObserver(callback, option);

IntersectionObserver 是瀏覽器原生提供的構造函數,接受兩個參數:

  • callback:可見性發現變化時的回調函數
  • option:配置對象(可選)。

構造函數的返回值是一個觀察器實例。實例一共有4個方法:

  • observe:開始監聽特定元素
  • unobserve:停止監聽特定元素
  • disconnect:關閉監聽工作
  • takeRecords:返回所有觀察目標的對象數組

1.1 observe 方法

該方法需要接收一個target參數,值是Element類型,用來指定被監聽的目標元素

// 獲取元素
const target = document.getElementById("dom");// 開始觀察
io.observe(target);

1.2 unobserve 方法

該方法需要接收一個target參數,值是Element類型,用來指定停止監聽的目標元素

// 獲取元素
const target = document.getElementById("dom");// 停止觀察
io.unobserve(target);

1.3 disconnect 方法

該方法不需要接收參數,用來關閉觀察器

// 關閉觀察器
io.disconnect();
// 頁面加載時監聽元素
onMounted(() => {var demo3 = document.querySelector('document.querySelector(dom))  //  獲取元素var observer = new IntersectionObserver((mutaions)=>{  // 創建IntersectionObserver對象console.log(mutaions[0].isIntersecting)})observer.observe(demo3)       // 需要監聽的元素 
}       

1.4 takeRecords 方法

該方法不需要接收參數,返回所有被觀察的對象,返回值是一個數組

// 獲取被觀察元素
const observerList = io.takeRecords();

1.5 callback 參數

目標元素的可見性變化時,就會調用觀察器的回調函數callback。

callback一般會觸發兩次。一次是目標元素剛剛進入視口,另一次是完全離開視口。

const io = new IntersectionObserver((changes, observer) => {console.log(changes);console.log(observer);
});

1.6 options

  • threshold: 決定了什么時候觸發回調函數。它是一個數組,每個成員都是一個門檻值,默認為[0],即交叉比例(intersectionRatio)達到0時觸發回調函數。用戶可以自定義這個數組。比如,[0, 0.25, 0.5, 0.75, 1]就表示當目標元素 0%、25%、50%、75%、100% 可見時,會觸發回調函數。
  • root: 用于觀察的根元素,默認是瀏覽器的視口,也可以指定具體元素,指定元素的時候用于觀察的元素必須是指定元素的子元素
  • rootMargin: 用來擴大或者縮小視窗的的大小,使用css的定義方法,10px 10px 30px 20px表示top、right、bottom 和 left的值

2. IntersectionObserverEntry 對象

changes數組中的每一項都是一個IntersectionObserverEntry 對象

  • boundingClientRect:目標元素的矩形區域的信息
  • intersectionRatio:目標元素的可見比例,即intersectionRect占
    boundingClientRect的比例,完全可見時為1,完全不可見時小于等于0
  • intersectionRect:目標元素與視口(或根元素)的交叉區域的信息
  • isIntersecting: 布爾值,目標元素與交集觀察者的根節點是否相交(常用)
  • isVisible: 布爾值,目標元素是否可見(該屬性還在試驗階段,不建議在生產環境中使用)
  • rootBounds:根元素的矩形區域的信息,getBoundingClientRect()方法的返回值,如果沒有根元素(即直接相對于視口滾動),則返回null
  • target:被觀察的目標元素,是一個 DOM 節點對象(常用)
  • time:可見性發生變化的時間,是一個高精度時間戳,單位為毫秒

3. 是否在可視區域

onMounted(() => {var observer = new IntersectionObserver((entries) => {console.log(111111, entries[0].isIntersecting);dataMap.showMyBox = !entries[0].isIntersecting; //返回true代表在頁面可視區域,false代表不在頁面可視區域。});observer.observe(document.querySelector(dom));
}
// 頁面卸載時可解綁
onBeforeUnmount(() => {if (observer) {observer.unobserve(document.querySelector(dom)); //解綁元素observer.disconnect(); //停止監聽}
});

4. 圖片懶加載

使用 IntersectionObserver 非常容易實現圖片懶加載,首先需要觀察懶加載元素,然后等元素進入可視區域后設置圖片 src;同時,還可以結合 IntersectionObserver.rootMargin 實現提前加載圖片,一般可以設置為 1~2 倍瀏覽器窗口的視口高度,優化用戶體驗

/*** @method lazyLoad* @param {NodeList} $imgList      圖片元素集合* @param {number}   preloadHeight 預加載高度*/
export function lazyLoad($imgList, preloadHeight = 1000) {const observer = new IntersectionObserver((entries) => {entries.forEach((entry) => {if (entry.isIntersecting) { // 目標元素出現在 root 可視區,返回 trueconst $target = entry.targetconst src = $target.getAttribute('lazyload')if (src) {$target.setAttribute('src', src) // 真正加載圖片}observer.unobserve($target) // 解除觀察}})}, {rootMargin: `0px 0px ${preloadHeight}px 0px`,})Array.prototype.forEach.call($imgList, ($item) => {if ($item.getAttribute('src')) return // 過濾已經加載過的圖片observer.observe($item) // 開始觀察})
}

使用方法:

// 圖片元素設置 lazyload 屬性
<img lazyload="圖片鏈接" alt="圖片說明">// 觀察圖片元素
lazyLoad(document.querySelectorAll("[lazyload]"))

5. 元素吸頂、吸底

如果頁面結構比較簡單可以直接使用 css 粘性布局。
IntersectionObserver 實現元素固定思路也很簡單,首先需要給固定元素包一層父元素,父元素指定高度占位,防止固定元素吸附時頁面抖動,然后觀察父元素的可視狀態變化,當父元素即將離開可視區域時改變固定元素的樣式。

/*** @method fixBanner* @param {HTMLElement} $observeEle 觀察元素* @param {HTMLElement} $fixEle     固定定位元素*/
export function fixBanner($observeEle, $fixEle) {const $ele = $fixEleconst observer = new IntersectionObserver((entries) => {entries.forEach((entry) => {if (entry.isIntersecting) {$ele.style.cssText = ''} else {$ele.style.cssText = 'position: fixed; top: 0; left: 0'}})}, {threshold: 1, // threshold 設置為 1 表示目標元素完全可見時觸發回調函數})observer.observe($observeEle) // 開始觀察
}

6. 加載更多

IntersectionObserver 實現加載更多需要在列表后面增加一個尾部元素(比如加載更多動畫),當尾部元素進入可視區域就加載更多數據,注意尾部元素一定要一直處于所有列表元素的后面。

提前加載高度不能隨意設置,如果設置太大會導致尾部元素一直處于可視狀態。

function loadMore() {const observer = new IntersectionObserver((entries) => {const loadingEntry = entries[0]if (loadingEntry.isIntersecting) {// 請求數據并插入列表}},{rootMargin: '0px 0px 600px 0px', // 提前加載高度},)observer.observe(document.querySelector('.mod_loading')) // 觀察尾部元素
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697577.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697577.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697577.shtml

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

相關文章

融中穿刺路徑角度評估的C++技術實現

消融模型的三維渲染 我們以肝部為例&#xff0c;通常肝部在做消融手術規劃時有幾個步驟。 一三維重建&#xff1a; 對器官進行圖像分割&#xff1b; 對腫瘤的原發區域GTV進行勾畫。 二穿刺路徑的規劃&#xff1a; 路徑規劃當中有幾個約束&#xff1a;穿刺深度、危及器官的…

OpenAI推出首個AI視頻模型Sora:重塑視頻創作與體驗

鏈接&#xff1a;華為OD機考原題附代碼 Sora - 探索AI視頻模型的無限可能 隨著人工智能技術的飛速發展&#xff0c;AI視頻模型已成為科技領域的新熱點。而在這個浪潮中&#xff0c;OpenAI推出的首個AI視頻模型Sora&#xff0c;以其卓越的性能和前瞻性的技術&#xff0c;引領著…

SpringBoot快速整合Thymeleaf實現文件上傳案例

SpringBoot快速整合Thymeleaf實現文件上傳案例 文章目錄 SpringBoot快速整合Thymeleaf實現文件上傳案例1. 創建工程2. pom.xml文件2. application.yml 配置3. 前端fileupload.html4. 后端Controller 本案例環境: SpringBoot: 2.3.0.RELEASEJDK: 1.8前端模板&#xff1a; thymel…

【PHP進階】Redis批處理緩存

大家好&#xff0c;我是程序員若風&#xff0c;又到了技術分享時刻。 概要 在某些場景下&#xff0c;我們需要頻繁的使用到緩存&#xff0c;比如需要獲取多個key值&#xff0c;如果采用單個拿緩存的辦法&#xff0c;會造成網絡IO極大的浪費&#xff0c;所以我們需要用戶Redis…

Leetcode3036. 匹配模式數組的子數組數目 II

Every day a Leetcode 題目來源&#xff1a;3036. 匹配模式數組的子數組數目 II 解法1&#xff1a;KMP 設數組 nums 的長度為 m&#xff0c;數組 pattern 的長度為 n。 遍歷數組 nums 的每個長度是 n1 的子數組并計算子數組的模式&#xff0c;然后與數組 pattern 比較&…

JavaScript 設計模式之觀察者模式

觀察者模式 觀察者模式又被稱為發布-訂閱模式&#xff0c;使用一個對象來收集訂閱者&#xff0c;在發布時遍歷所有訂閱者&#xff0c;然后將信息傳遞給訂閱者&#xff0c;可以這樣來實現一個簡單的模式 const Observable (function () {let __messages {}return {register:…

win系統下安裝mysql5.7并配置環境變量、設置root用戶和服務啟動的詳細操作教程

本篇文章主要講解&#xff1a;win系統下安裝mysql5.7并配置環境變量、設置root用戶和服務啟動的詳細操作教程 日期&#xff1a;2024年2月22日 作者&#xff1a;任聰聰 一、mysql5.7版本的下載 官方下載地址&#xff1a;https://downloads.mysql.com/archives/community/ 步驟…

服務器生信環境配置腳本

服務器生信環境配置腳本的重要性在于它為生物信息學的數據分析提供了一個統一和標準化的計算環境。通過自動化的配置腳本&#xff0c;可以快速地在服務器上部署和設置生物信息學的軟件和依賴庫&#xff0c;確保分析的可重復性和準確性。這樣&#xff0c;生物信息學家和研究人員…

【鴻蒙 HarmonyOS 4.0】狀態管理

一、介紹 資料來自官網&#xff1a;文檔中心 在聲明式UI編程框架中&#xff0c;UI是程序狀態的運行結果&#xff0c;用戶構建了一個UI模型&#xff0c;其中應用的運行時的狀態是參數。當參數改變時&#xff0c;UI作為返回結果&#xff0c;也將進行對應的改變。這些運行時的狀…

Stable Diffusion 模型的概念、類型、下載、安裝、使用

本文收錄于《AI繪畫從入門到精通》專欄&#xff0c;專欄總目錄&#xff1a;點這里。 大家好&#xff0c;我是水滴~~ 我們在《Stable Diffusion WebUI 界面介紹》 時&#xff0c;第一個就講到了 Stable Diffusion 模型&#xff0c;那么這個模型是什么&#xff1f;該從哪兒下載&…

多輸入分類|GWO-CNN-LSTM|灰狼算法優化的卷積-長短期神經網絡分類預測(Matlab)

目錄 一、程序及算法內容介紹&#xff1a; 基本內容&#xff1a; 亮點與優勢&#xff1a; 二、實際運行效果&#xff1a; 三、算法介紹&#xff1a; 灰狼優化算法&#xff1a; 卷積神經網絡-長短期記憶網絡&#xff1a; 四、完整程序下載&#xff1a; 一、程序及算法內容…

【EI會議征稿通知】第五屆人工智能與機電自動化國際學術會議(AIEA 2024)

第五屆人工智能與機電自動化國際學術會議&#xff08;AIEA 2024&#xff09; 2024 5th International Conference on Artificial Intelligence and Electromechanical Automation 優秀評選已啟動&#xff0c;設置優秀論文、優秀報告及優秀海報多個獎項&#xff0c;豐厚獎金等…

【Java程序設計】【C00280】基于Springboot的校友社交系統(有論文)

基于Springboot的校友社交系統&#xff08;有論文&#xff09; 項目簡介項目簡介項目獲取開發環境項目技術運行截圖 項目簡介 項目簡介 這是一個基于Springboot的校友社交系統 本系統分為系統功能模塊、管理員功能模塊以及用戶功能模塊。 系統功能模塊&#xff1a;在系統首頁…

數據結構與算法——排序算法

目錄 文章目錄 前言 一.排序的基本概念 1.什么是就地排序 2.什么是內部排序和外部排序 3.什么是穩定排序 4.判定一個排序算法的是穩定的 二.插入排序算法 1.直接插入排序 1.1基本思想 1.2復雜度 1.3穩定性 1.4代碼演示 2.折半插入排序 2.1基本思想 2.2性能 3.…

vue實現遞歸組件

父組件&#xff1a; <Tree :data"data"></Tree> import Tree from "/components/Tree.vue"; const data reactive([{name: "1",checked: true,children: [{name: "1-1",checked: false,},],},&#xff09; 子組件&#…

若依logback日志配置采坑

問題描述 若依使用的appender過濾器是level&#xff0c;如下述代碼&#xff0c;這種過濾器只能導出級別為INFO的日志&#xff0c;warn和error都導出不出來。查詢不是很方便。 <!-- 系統日志輸出 --><appender name"file_info" class"ch.qos.logback.…

JAVA IDEA 項目打包為 jar 包詳解

前言 如下簡單 maven 項目&#xff0c;現在 maven 項目比較流行&#xff0c;你還沒用過就OUT了。需要打包jar 先設置&#xff1a;點擊 File > Project Structure > Artifacts > 點擊加號 > 選擇JAR > 選擇From modules with dependencies 一、將所有依賴和模…

VirtualBox+Vagrant快速搭建Centos7

目錄 安裝VirtualBox&#xff1a; 安裝Vagrant&#xff1a; 創建Vagrant項目目錄&#xff1a; 初始化Vagrant配置文件&#xff1a; 本地Vagrantfile中的鏡像名稱&#xff1a; 啟動虛擬機&#xff1a; SSH登錄虛擬機&#xff1a; 備注&#xff1a;安裝鏡像的另一種方式是…

springmvc+ssm+springboot房屋中介服務平臺的設計與實現 i174z

本論文擬采用計算機技術設計并開發的房屋中介服務平臺&#xff0c;主要是為用戶提供服務。使得用戶可以在系統上查看房屋出租、房屋出售、房屋求購、房屋求租&#xff0c;管理員對信息進行統一管理&#xff0c;與此同時可以篩選出符合的信息&#xff0c;給筆者提供更符合實際的…

Autodesk CAD如何建立圖層方框?

在AutoCAD中&#xff0c;要建立圖層方框&#xff08;Layer Box&#xff09;可以通過以下步驟實現&#xff1a; 打開圖層管理器&#xff1a; 在 AutoCAD 中&#xff0c;您可以通過輸入“LA”命令或在菜單欄中選擇“格式” > “圖層管理器”來打開圖層管理器對話框。 創建新圖…