IntersectionObserver對象

IntersectionObserver對象

IntersectionObserver對象,從屬于Intersection Observer API,提供了一種異步觀察目標元素與其祖先元素或頂級文檔視窗viewport交叉狀態的方法,祖先元素與視窗viewport被稱為根root,也就是說IntersectionObserver API,可以自動觀察元素是否可見,由于可見visible的本質是,目標元素與視口產生一個交叉區,所以這個API叫做交叉觀察器,兼容性https://caniuse.com/?search=IntersectionObserver

描述

IntersectionObserver解決了一個長期以來Web的問題,觀察元素是否可見,這個可見visible的本質是,目標元素與視口產生一個交叉區,所以這個API叫做交叉觀察器。
要檢測一個元素是否可見或者兩個元素是否相交并不容易,很多解決辦法不可靠或性能很差。現在很多需求下都需要用到相交檢測,例如圖片懶加載、內容無限滾動、檢測元素的曝光情況、可視區域播放動畫等等,相交檢測通常要用到onscroll事件監聽,并且可能需要頻繁調用Element.getBoundingClientRect()等方法以獲取相關元素的邊界信息,事件監聽和調用Element.getBoundingClientRect都是在主線程上運行,因此頻繁觸發、調用可能會造成性能問題,這種檢測方法極其怪異且不優雅。
Intersection Observer API會注冊一個回調函數,每當被監視的元素進入或者退出另外一個元素時或viewport,或者兩個元素的相交部分大小發生變化時,該回調方法會被觸發執行,這樣網站的主線程不需要再為了監聽元素相交而辛苦勞作,瀏覽器會自行優化元素相交管理,注意Intersection Observer API無法提供重疊的像素個數或者具體哪個像素重疊,他的更常見的使用方式是當兩個元素相交比例在N%左右時,觸發回調,以執行某些邏輯。

const io = new IntersectionObserver(callback, option);// 開始觀察
io.observe(document.getElementById("example"));
// 停止觀察
io.unobserve(element);
// 關閉觀察器
io.disconnect();
  • 參數callback,創建一個新的IntersectionObserver對象后,當其監聽到目標元素的可見部分穿過了一個或多個閾thresholds時,會執行指定的回調函數。
  • 參數optionIntersectionObserver構造函數的第二個參數是一個配置對象,其可以設置以下屬性:
    • threshold屬性決定了什么時候觸發回調函數,它是一個數組,每個成員都是一個門檻值,默認為[0],即交叉比例intersectionRatio達到0時觸發回調函數,用戶可以自定義這個數組,比如[0, 0.25, 0.5, 0.75, 1]就表示當目標元素0%25%50%75%100%可見時,會觸發回調函數。
    • root屬性指定了目標元素所在的容器節點即根元素,目標元素不僅會隨著窗口滾動,還會在容器里面滾動,比如在iframe窗口里滾動,這樣就需要設置root屬性,注意,容器元素必須是目標元素的祖先節點。
    • rootMargin屬性定義根元素的margin,用來擴展或縮小rootBounds這個矩形的大小,從而影響intersectionRect交叉區域的大小,它使用CSS的定義方法,比如10px 20px 30px 40px,表示toprightbottomleft四個方向的值。
  • 屬性IntersectionObserver.root只讀,所監聽對象的具體祖先元素element,如果未傳入值或值為null,則默認使用頂級文檔的視窗。
  • 屬性IntersectionObserver.rootMargin只讀,計算交叉時添加到根root邊界盒bounding box的矩形偏移量,可以有效的縮小或擴大根的判定范圍從而滿足計算需要,此屬性返回的值可能與調用構造函數時指定的值不同,因此可能需要更改該值,以匹配內部要求,所有的偏移量均可用像素pixelpx或百分比percentage%來表達,默認值為0px 0px 0px 0px
  • 屬性IntersectionObserver.thresholds只讀,一個包含閾值的列表,按升序排列,列表中的每個閾值都是監聽對象的交叉區域與邊界區域的比率,當監聽對象的任何閾值被越過時,都會生成一個通知Notification,如果構造器未傳入值,則默認值為0
  • 方法IntersectionObserver.disconnect(),使IntersectionObserver對象停止監聽工作。
  • 方法IntersectionObserver.observe(),使IntersectionObserver開始監聽一個目標元素。
  • 方法IntersectionObserver.takeRecords(),返回所有觀察目標的IntersectionObserverEntry對象數組。
  • 方法IntersectionObserver.unobserve(),使IntersectionObserver停止監聽特定目標元素。

此外當執行callback函數時,會傳遞一個IntersectionObserverEntry對象參數,其提供的信息如下。

  • time:可見性發生變化的時間,是一個高精度時間戳,單位為毫秒。
  • target:被觀察的目標元素,是一個DOM節點對象。
  • rootBounds:根元素的矩形區域的信息,是getBoundingClientRect方法的返回值,如果沒有根元素即直接相對于視口滾動,則返回null
  • boundingClientRect:目標元素的矩形區域的信息。
  • intersectionRect:目標元素與視口或根元素的交叉區域的信息。
  • intersectionRatio:目標元素的可見比例,即intersectionRectboundingClientRect的比例,完全可見時為1,完全不可見時小于等于0

應用

實現一個使用IntersectionObserver的簡單示例,兩個方塊分別可以演示方塊1是否在屏幕可見區域內以及方塊2是否在方塊1的相對可見交叉區域內,另外可以使用IntersectionObserver可以進行首屏渲染的優化,可以參考https://github.com/WindrunnerMax/EveryDay/blob/master/Vue/Vue%E9%A6%96%E5%B1%8F%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E7%BB%84%E4%BB%B6.md

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style> body{margin: 0;padding: 0;height: 100vh;width: 100vw;overflow-x: hidden;}.flex{display: flex;}.top-fixed{top: 0;position: fixed;}.placeholder1{width: 100%;}#box1{height: 200px; overflow-y: auto; border: 1px solid #aaa; width: 60%;}.box1-placeholder{height: 105vh;}#box2{height: 100px; background-color: blue; margin-top: 300px; width: 60%;}.box2-placeholder{height: 205px;}</style>
</head>
<body><section class="flex top-fixed"><div class="flex">BOX1:</div><div class="flex" id="box1-status">invisible</div><div class="flex">&nbsp;BOX2:</div><div class="flex" id="box2-status">invisible</div></section><div class="box1-placeholder"></div><div id="box1"><div class="box2-placeholder"></div><div id="box2"></div>   <div class="box2-placeholder"></div></div><div class="box1-placeholder"></div></body>
<script>(function(){const box1 = document.querySelector("#box1");const box2 = document.querySelector("#box2");const box1Status = document.querySelector("#box1-status");const box2Status = document.querySelector("#box2-status");const box1Observer = new IntersectionObserver(entries => {entries.forEach(item => {// `intersectionRatio`為目標元素的可見比例,大于`0`代表可見if (item.intersectionRatio > 0) {box1Status.innerText = "visible";}else{box1Status.innerText = "invisible";}});}, {root: document});const box2Observer = new IntersectionObserver(entries => {entries.forEach(item => {// `intersectionRatio`為目標元素的可見比例,大于`0`代表可見if (item.intersectionRatio > 0) {box2Status.innerText = "visible";}else{box2Status.innerText = "invisible";}});}, {root: box1});box1Observer.observe(box1);box2Observer.observe(box2);})();
</script>
</html>

每日一題

https://github.com/WindrunnerMax/EveryDay

參考

https://www.jianshu.com/p/eadd83d794c8
https://www.ruanyifeng.com/blog/2016/11/intersectionobserver_api.html
https://developer.mozilla.org/zh-CN/docs/Web/API/IntersectionObserver

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

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

相關文章

c#---多態

在 C#語言中體現多態有三種方式&#xff1a;虛方法&#xff0c;抽象類&#xff0c; 接口 一、虛方法 什么是虛方法&#xff1f; 在父類中使用 virtual 關鍵字修飾的方法&#xff0c; 就是虛方法。在子類中可以使用 override 關鍵字對該虛方法進行重寫。 class Animal {public…

android apk沒有源碼如何修改程序

如果您擁有一個APK文件但沒有源代碼&#xff0c;您可以嘗試以下幾種方法來進行修改&#xff1a; 反編譯APK&#xff1a;使用工具如apktool對APK文件進行反編譯&#xff0c;這將為您提供源代碼和資源文件。 動態調試&#xff1a;使用調試工具連接設備或模擬器&#xff0c;并動態…

重裝前端整體流程

用戶管理 --匯總 -- 明細-CSDN博客 一、node 這個看環境變量 2023最新版Node.js下載安裝及環境配置教程&#xff08;非常詳細&#xff09;從零基礎入門到精通&#xff0c;看完這一篇就夠了_nodejs安裝及環境配置-CSDN博客 配置到國內鏡像的時候&#xff0c;去看&#xff0c;淘…

理解固化的Maven依賴:spring-boot-starter-parent 與 spring-boot-dependencies

目錄 理解固化的Maven依賴&#xff1a;spring-boot-starter-parent 與 spring-boot-dependencies1. spring-boot-starter-parent1.1 簡介1.2 特點 2. spring-boot-dependencies2.1 簡介2.2 特點 3. 異同點對比3.1 相同點3.2 不同點案例一&#xff1a;使用 spring-boot-starter-…

Java方法的重載

方法重載 1. 為什么需要方法重載 public class TestMethod{public static void main (String[] args){int a 10;int b 20;int ret add(a,b);System.out.println("ret "ret);double a2 10.5;double b2 20.5;double ret2 add(a2,b2);System.out.println("…

《QT實用小工具·六十二》基于QT實現貝塞爾曲線畫炫酷的波浪動畫

1、概述 源碼放在文章末尾 該項目實現了通過貝塞爾曲線畫波浪動畫&#xff0c;可控制 顏色密度速度加速度 安裝與運行環境 語言&#xff1a;C 框架&#xff1a;Qt 11.3 平臺&#xff1a;Windows 將屏幕水平平均分為10塊&#xff0c;在一定范圍內隨機高度的12個點&#xff08;…

飛天使-k8s知識點29-kubernetes安裝1.28.0版本

文章目錄 選用版本初始化服務器,自己修改里面的ipreboot haproxy安裝 &#xff0c;可以參考我之前寫的內核參數調整&#xff0c;安裝docker 安裝cri-dockerd開始安裝集群工具下載鏡像以及啟用完畢之后 此時的coredns 不通結果展示 選用版本 k8s 1.24版本之前還可以使用docker&…

【初階數據結構】順序表OJ題講解

前言 &#x1f4da;作者簡介&#xff1a;愛編程的小馬&#xff0c;正在學習C/C&#xff0c;Linux及MySQL。 &#x1f4da;本文收錄與初階數據結構系列&#xff0c;本專欄主要是針對時間、空間復雜度&#xff0c;順序表和鏈表、棧和隊列、二叉樹以及各類排序算法&#xff0c;持…

基于ambari hdp的kafka用戶授權讀寫權限

基于ambari hdp的kafka用戶授權讀寫權限 版本Kafka 2.0.0添加自定義配置修改admin密碼重啟kafka授權讀取授權寫入有效通配符部分舉例 版本Kafka 2.0.0 添加自定義配置 authorizer.class.name kafka.security.auth.SimpleAclAuthorizer super.users User:admin allow.everyo…

【LLM 論文】Step-Back Prompting:先解決更高層次的問題來提高 LLM 推理能力

論文&#xff1a;Take a Step Back: Evoking Reasoning via Abstraction in Large Language Models ???? Google DeepMind, ICLR 2024, arXiv:2310.06117 論文速讀 該論文受到的啟發是&#xff1a;人類再解決一個包含很多細節的具體問題時&#xff0c;先站在更高的層次上解…

Android 屏幕適配全攻略(上)-掌握屏幕單位,應對千變萬化的設備

本文從 Android 開發中常見的長度單位 px、dp、sp 入手&#xff0c;詳細介紹了它們的特點及轉換關系。 接著深入探討了屏幕尺寸、分辨率、像素密度等重要的屏幕指標&#xff0c;幫助讀者全面理解它們之間的聯系。最后&#xff0c;通過實例代碼演示了如何在代碼中進行單位轉換&…

三分鐘上手安全滲透系統Kali Linux

kali linux系統集成了常用的安全滲透工具&#xff0c;省去了安裝工具的時間&#xff0c;做安全相關的工作是非常推薦使用的。 安裝Kalii Linux 安裝系統 一般使用虛擬機進行安裝&#xff0c;Kali Linux基于Debian內核&#xff0c;虛擬機的操作系統選擇Debian 7.x 64 選擇系統…

【SRC實戰】一鍵完成全部任務獲取獎勵

挖個洞先 https://mp.weixin.qq.com/s/LkPfJuuP1K8vaFXRn-8wVg “ 以下漏洞均為實驗靶場&#xff0c;如有雷同&#xff0c;純屬巧合 ” 01 — 漏洞證明 一、業務邏輯 “ 如何欺騙APP完成任務獲取獎勵&#xff1f; ” 1、記錄金幣數量20 2、瀏覽商品詳情頁 3、點擊瀏覽提…

我們應該如何做參與式觀察

記得多年以前&#xff0c;有個朋友問我&#xff1a;對于做觀察&#xff0c;有人通過教授繪畫技巧來教人如何做觀察。你們研究員又不會畫畫&#xff0c;你們如何讓人相信你們更會觀察呢&#xff1f;坦率說&#xff0c;當時我被問住了&#xff0c;因為我從來沒有進行過這樣的對比…

day5Qt作業

服務器端 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//準備組件&#xff0c;初始化組件狀態this->setFixedSize(800,600);chatwidget new QListWidge…

代碼隨想錄算法訓練營第四十九天| 123.買賣股票的最佳時機III,188.買賣股票的最佳時機IV

目錄 題目鏈接&#xff1a;123.買賣股票的最佳時機III 思路 代碼 題目鏈接&#xff1a;188.買賣股票的最佳時機IV 思路 代碼 總結 題目鏈接&#xff1a;123.買賣股票的最佳時機III 思路 與之前買賣股票不同的是本題要求最多買賣兩次&#xff0c;那么dp數組以及遞推公式都…

攻擊者正在利用AI,對保險公司發起大規模欺詐

保險欺詐一直是保險行業面臨的重要挑戰之一&#xff0c;尤其隨著技術的進步&#xff0c;欺詐者也在不斷更新其手段&#xff0c;利用AI技術&#xff0c;包括生成式模型、機器學習和數據分析工具等欺騙保險公司&#xff0c;而AI技術的應用正成為他們的新工具&#xff0c;使其犯罪…

如何打造個人IP?

打造個人IP&#xff08;Intellectual Property&#xff09;是當今社會中越來越受到關注的話題。個人IP指的是個人在某個領域內所擁有的獨特的、具有商業價值的知識、技能、品牌和影響力。為什么要打造個人IP&#xff1f;如何打造個人IP&#xff1f;下面我將為您詳細解答。 首先…

Navicat連接遠程數據庫時,隔一段時間不操作出現的卡頓問題

使用 Navicat 連接服務器上的數據庫時&#xff0c;如果隔一段時間沒有使用&#xff0c;再次點擊就會出現卡頓的問題。 如&#xff1a;隔一段時間再查詢完數據會出現&#xff1a; 2013 - Lost connection to MySQL server at waiting for initial communication packet, syste…

LinkedList鏈表

LinkedList 的全面說明 LinkList底層實現了雙向鏈表和雙端隊列特點可以添加任意元素&#xff08;元素可以重復&#xff09;&#xff0c;包括null線程不安全&#xff0c;沒有實現同步 LinkedList 的底層操作機制 LinkedList底層維護了一個雙向鏈表LinkList中維護了兩個屬性fi…