<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
作為一個前端搬磚仔,偶爾會遇到關於視窗的問題...
其中就經常會遇到一些資料上報問題,比如某某元件是否被使用者看到了,如果看到就要上報資料,讓產品同學方便進行資料分析。
分析這個場景可以發現,必須要使用者看到了我才能上報,怎麼判斷使用者是否看到了這個元件呢?
傳統的方法是操作dom,通過這些資料或方法(offsetTop、scrollTop,getBoundingClientRect)來進行比較。
頻繁的對DOM狀態的計算,會造成不小的效能損耗,導致頁面卡頓。
接下來介紹一種我最近比較常用的新方式:Intersection Observer(交叉觀察器)
Intersection Observer 翻譯過來即交叉觀察器
主要是用於監聽目標元素與指定的元素視窗是否發生交叉
一句話總結:Intersection Observer API 提供了一種非同步檢測目標元素與祖先元素或 viewport 相交情況變化的方法。 – MDN
<template> <div class="home"></div> </template> <script> export default { name: "HomeView", mounted() { // 可見性發生變化後的回撥 function callback() { console.log("觸發了"); } // 交叉觀察器設定項 let options = {}; // 生成交叉觀察器 const observer = new IntersectionObserver(callback); }, }; </script>
(callback是當元素可見比例超過指定閾值後會呼叫的一個回撥函數,options是一個可以用來設定 observer 範例的物件。)
輸出一下IntersectionObserver建構函式返回的範例
root:root 屬性用來獲取當前 intersectionObserver 範例的根元素,用於判斷元素是否可見區域。
(注:這個既可以是 target 元素祖先元素也可以是指定 null 則使用瀏覽器視口 做為容器 (root)。)
rootMargin:一個類似於margin的字串引數,就可以使用 root margin 來調整根矩形大小。
(注:由於使用Intersection Observer的過程中所有區域均被當做一個矩形看待,因此當我們需要調整元素邊界的矩形時,用 root margin 來調整大小。)
threshold:閾值,可以傳一個0 ~ 1的number,也可以傳個0 ~ 1範圍的number陣列。
(注:如果傳一個0 ~ 1的number,如0.5則說明,目標元素和root相交超過50%時,即二者重合超過目標元素的50%時,觸發回撥,如果是一個陣列[0.1, 0.2, 0.5]則分別在10% 20% 50%處觸發回撥)
<template> <div class="home"> <div id="target" class="target-item"></div> </div> </template> <script> export default { name: "HomeView", mounted() { // 可見性發生變化後的回撥 function callback(data) { console.log("觸發了"); console.log(data); } // 交叉觀察器設定項 let options = {}; // 生成交叉觀察器 const observer = new IntersectionObserver(callback); // 獲取目標節點 let target = document.getElementById("target"); // 監聽目標元素 observer.observe(target); }, }; </script> <style scoped> .home { height: 300vh; } .home .target-item { margin-top: 120vh; width: 20px; height: 20px; background: #000; } </style>
可以看到
通過捲動,可以不停監聽到觀察器的回撥。
看到在觀察器的回撥中是返回了一個物件的,修改原來的回撥函數,對應看看到底返回了啥?
export default { name: "HomeView", mounted() { // 可見性發生變化後的回撥 function callback(data) { console.log("觸發了"); data.map((item) => { // 目標元素的getBoundingClientRect的返回值。 console.log(item.boundingClientRect); // 目標元素和根元素交叉區域的getBoundingClientRect的返回值。 console.log(item.intersectionRatio); // 目標元素的可見比例,相當於二者重合了多少。 console.log(item.intersectionRect); // 目標元素與根元素是否相交 console.log(item.isIntersecting); // 根元素的getBoundingClientRect的返回值 console.log(item.rootBounds); // 目標元素,是個dom console.log(item.target); // 從首次建立觀察者到觸發指定閾值發生交叉的時間 console.log(item.time); }); } // 交叉觀察器設定項 let options = { threshold: 0.5, }; // 生成交叉觀察器 const observer = new IntersectionObserver(callback, options); // 獲取目標元素 let target = document.getElementById("target"); // 監聽目標元素 observer.observe(target); }, };
可以看到控制檯輸出了下述內容:
可以看到返回了很多東西
其中就有我們熟悉的元素的getBoundingClientRect屬性。
boundingClientRect: 物件,返回了目標元素的getBoundingClientRect的返回值。
intersectionRatio:物件,返回了目標元素和根元素交叉區域的getBoundingClientRect的返回值。
intersectionRect: 數位,目標元素的可見比例,相當於二者重合了多少。
isIntersecting: 布林值,目標元素與根元素相交是否相交
(如果相交,則返回 true ,若為true則說明至少到達了一個閾值,如果為false,說明目標元素在閾值範圍內不可見)
rootBounds: 物件,返回了根元素的getBoundingClientRect的返回值。
target:物件,目標元素,是個dom
time: 數位,從首次建立觀察者到觸發指定閾值發生交叉的時間
因此通過觀察器的回撥引數可以做到精確監聽目標的,通過這些引數可以更好的支援如下拉載入技術上報等場景,由於該屬性是原生api因此比起頻繁的操作dom會來的更絲滑。
通過上文我們已經說明了,如何使用交叉觀察器,並介紹了觀察器的範例屬性及回撥引數
下面說一下觀察器的實體方法!
// 生成交叉觀察器 const observer = new IntersectionObserver(callback, options); // 獲取目標元素 let target = document.getElementById("target"); // 監聽目標元素 observer.observe(target);
可以看到監聽目標元素的時候用了 observe 方法,這就是觀察器的實體方法之一—— 監聽目標元素
觀察器的實體方法一共有四個
disconnect:停止對所有的目標元素的觀察
observe:監聽目標元素(可監聽多個)
takeRecords:返回一個IntersectionObserverEntry物件陣列(觀察器回撥引數就是這個),裡面存放的各個目標元素的相交資訊
unobserve:停止對一個指定目標元素的觀察
通過程式碼來演示下上述方法:
<template> <div class="home"> <div id="target1" class="target1-item"></div> <div id="target2" @click="unobserve()" class="target2-item"></div> <div style="margintop: 10px" @click="disconnect">disconnect</div> </div> </template> <script> export default { name: "HomeView", data() { return { observer: {}, }; }, mounted() { // 可見性發生變化後的回撥 function callback(data) { console.log(data[0].target.id); } // 生成交叉觀察器 this.observer = new IntersectionObserver(callback); // 獲取目標元素1 let target1 = document.getElementById("target1"); // 獲取目標元素2 let target2 = document.getElementById("target2"); // 監聽目標元素1 this.observer.observe(target1); // 監聽目標元素2 this.observer.observe(target2); }, methods: { unobserve() { let target2 = document.getElementById("target2"); // 停止監聽目標元素2 this.observer.unobserve(target2) }, disconnect() { // 停止監聽所有目標元素 this.observer.disconnect(); }, }, }; </script>
程式碼效果如下所示:
可以看到一開始是監聽元素1和元素2,接著停止元素2的監聽,最後停止所有元素的監聽
以上就是Intersection Observer(交叉觀察器)的基本使用了。
(1)利用IntersectionObserver建構函式建立一個觀察器範例,設定其回撥和基本引數
// 可見性發生變化後的回撥 function callback() { } // 生成交叉觀察器 this.observer = new IntersectionObserver(callback);
(2)獲取目標元素節點,並監聽該元素
// 獲取目標元素 let target = document.getElementById("target"); // 監聽目標元素 this.observer.observe(target);
(3)回撥中處理相關邏輯
function callback(data) { console.log(data) }
(4)觀察器使用結束後,取消對元素的監聽
// 停止觀察某個目標元素 observer.unobserve(target); // 關閉監視器 observer.disconnect();
聊聊Intersection Observer各大瀏覽器的支援性 截圖自
總的來說,這個還是適用於很多瀏覽器的。
各位前端朋友,如果以後有遇到下拉載入或資料上報的場景的話不妨使用一下這個Intersection Observer
確實是一個開發的好工具。
以上就是Intersection Observer交叉觀察器範例解析的詳細內容,更多關於Intersection Observer交叉觀察器的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45