Intersection Observer API:實時監控元素是否可見
你可能不知道,JavaScript 近年來悄然積累了許多觀察者,而Intersection Observer 正是其中一種強大的工具。觀察者是實時監控特定事件的對象,就像觀鳥者坐在他們最喜歡的地方等待鳥兒出現一樣。不同的觀察者觀察不同的目標。
我最早接觸到的觀察者是Mutation Observer,它用於檢測DOM 樹的更改。當時它是獨一無二的,但現在我們有了更多觀察者。
Intersection Observer 觀察元素與其祖先元素或頁面可見區域(即視口)之間的“交叉”(即元素進入或離開視口)。這有點像觀看火車經過車站。你可以看到火車何時進站、何時離站以及它停站了多久。
了解元素何時即將進入視野、何時消失或自進入視野以來已過去多長時間,都具有非常實用的應用。因此,我們將了解一些用例——在通過Intersection Observer API 創建IntersectionObserver 對象的代碼之後。
IntersectionObserver 快速概述
在撰寫本文時,Intersection Observer API 已經獲得了廣泛的支持。
瀏覽器支持數據來自Caniuse,其中包含更多詳細信息。數字表示瀏覽器在該版本及更高版本中支持該功能。
桌面端
移動/平板
但是,如果你想在使用Intersection Observer 時檢查它是否受支持,你可以查看window 對像中是否存在IntersectionObserver 屬性:
if(!!window.IntersectionObserver){} /* or */ if('IntersectionObserver' in window){}
好的,現在來看一下對象的創建:
var observer = new IntersectionObserver(callback, options);
IntersectionObserver 對象的構造函數接受兩個參數。第一個是回調函數,當觀察者註意到交叉並異步傳遞有關該交叉的一些數據時,該函數將被執行。
第二個(可選)參數是options ,一個包含信息的對象,用於定義什麼是“交叉”。我們可能不想知道元素何時即將進入視野,而只想在它完全可見時才知道。諸如此類的事情是通過options 參數定義的。
Options 有三個屬性:
- root – 被觀察元素將與其交叉的祖先元素/視口。把它想像成火車將與其交叉的車站。
- rootMargin – 根元素的周長,縮小或擴大根元素的觀察區域以檢測交叉。它類似於CSS margin 屬性。
- threshold – 值(介於0 和1.0 之間)的數組,每個值代表元素與根交叉或越過根的距離,在此距離下將觸發回調。
假設我們的threshold 為0.5。當元素進入或超過其半可見閾值時,將觸發回調。如果值為[0.3, 0.6]
,則當元素進入或超過其30% 可見閾值以及其60% 可見閾值時,將觸發回調。
現在理論就講到這裡。讓我們看一些演示。首先是懶加載。
用例1:懶加載圖像
要查看加載標記
,請查看此網頁,因為嵌入式演示不會顯示該標記。
CSS-Tricks 之前已經徹底介紹了懶加載,通常是這樣完成的:顯示一個輕量級佔位符,圖像將顯示在該佔位符的位置,然後在圖像進入(或即將進入)視野時將其替換為預期的圖像。相信我,實現這一點一點也不懶惰——也就是說,直到我們得到一些原生代碼來使用。
我們將應用相同的機制。首先,我們有一堆圖像,並定義了一個初始顯示的佔位符圖像。我們使用一個數據屬性來攜帶要顯示的原始圖像的URL,該屬性定義了實際圖像在進入視野時要加載的圖像。
<img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174520555311750.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="A Few Functional Uses for Intersection Observer to Know When an Element is in View"><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174520555481250.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="A Few Functional Uses for Intersection Observer to Know When an Element is in View"><img src="/static/imghwm/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/174520555431263.jpg?x-oss-process=image/resize,p_40" class="lazy" alt="A Few Functional Uses for Intersection Observer to Know When an Element is in View">
其餘的是腳本。
let observer = new IntersectionObserver( (entries, observer) => { entries.forEach(entry => { /* 在這里處理每個交叉*/ }); }, {rootMargin: "0px 0px -200px 0px"});
上面的回調函數是一個箭頭函數(儘管你可以使用普通函數)。
回調函數接收兩個參數:一組entries ,包含有關每個交叉的信息;以及observer本身。可以過濾或循環遍歷這些entries,然後處理我們想要的交叉entries。至於options,我只提供了rootMargin 值,讓root 和threshold 屬性採用其默認值。
root 的默認值為視口,threshold 的默認值為0——這大致可以解釋為“元素出現在視口的那一刻就通知我!”
然而,奇怪的是,我使用rootMargin 將視口的觀察區域底部減少了200 像素。我們通常不會在懶加載中這樣做。相反,我們可能會增加邊距或讓它保持默認值。但是,在這種情況下,我們通常不會減少邊距。我這樣做只是因為我想演示在觀察區域的閾值處加載的原始圖像。否則,所有操作都將在視野外發生。
當圖像與視口的觀察區域(在演示中距離底部上方200 像素)相交時,我們將佔位符圖像替換為實際圖像。
let observer = new IntersectionObserver( (entries, observer) => { entries.forEach(entry => { /* 佔位符替換*/ entry.target.src = entry.target.dataset.src; observer.unobserve(entry.target); }); }, {rootMargin: "0px 0px -200px 0px"});
entry.target
是被觀察者觀察的元素。在我們的例子中,這些是圖像元素。一旦在圖像元素中替換了佔位符,我們就無需再觀察它了,因此我們對其調用觀察者的unobserve
方法。
現在觀察者已準備就緒,是時候使用其observe
方法開始觀察所有圖像了:
document.querySelectorAll('img').forEach(img => { observer.observe(img) });
就是這樣!我們已經懶加載了圖像。進入下一個演示。
用例2:元素離開視野時自動暫停視頻
假設我們在YouTube 上觀看視頻,並且(無論出於何種原因)我們想要向下滾動以閱讀評論。我不知道你怎麼樣,但我通常不會在這樣做之前先暫停視頻,這意味著我在瀏覽時會錯過一些視頻。
如果當我們從視頻滾動離開時視頻會自動暫停,那不是很好嗎?如果視頻在重新進入視野時恢復播放,那就更好了,這樣就無需點擊播放或暫停按鈕了。
Intersection Observer 當然可以做到這一點。
這是我們在HTML 中的視頻:
<video controls="" src="OSRO-animation.mp4"></video>
這是我們在每次交叉(即entry)期間暫停和播放視頻的方式:
let video = document.querySelector('video'); let isPaused = false; /* 自動暫停視頻的標誌*/ let observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if(entry.intersectionRatio!=1 && !video.paused){ video.pause(); isPaused = true; } else if(isPaused) {video.play(); isPaused=false} }); }, {threshold: 1}); observer.observe(video);
在我向你展示如何在每次交叉(即entry)期間暫停和播放視頻之前,我想提請你注意options 的threshold 屬性。
threshold 的值為1。 root 和rootMargin 將採用默認值。這等同於說:“嘿,一旦元素在視口中完全可見,就通知我。”
一旦發生交叉並觸發回調,我們將根據以下邏輯暫停或播放視頻:
我沒有為視頻調用unobserve
,因此觀察者會一直觀察視頻,並在每次視頻離開視野時暫停。
用例3:查看已查看內容的多少
這可以根據你的內容和你首選的衡量已查看內容多少的方式以多種方式解釋和實現。
對於一個簡單的示例,我們將觀察頁面上文章列表中每篇文章的最後一段。一旦文章的最後一段完全可見,我們將認為該文章已閱讀——就像我們可能會說看到火車的最後一節車廂就等於看到了整列火車一樣。
這是一個演示,它顯示頁面上的兩篇文章,每篇文章包含多段文字。
我們簡化的HTML 如下所示:
<div></div> <h2 id="Article">Article 1</h2> <p></p> <h2 id="Article">Article 2</h2> <p></p>
let n=0; /* 已查看的文章總數*/ let count = document.querySelector('#count'); let observer = new IntersectionObserver((entries, observer) => { entries.forEach(entry => { if(entry.isIntersecting){ count.textContent= `articles fully viewed - ${ n}`; observer.unobserve(entry.target); } }); }, {threshold: 1}); document.querySelectorAll('article > p:last-child').forEach(p => { observer.observe(p) });
在每次交叉(即文章的最後一段完全可見)期間,我們都會遞增一個計數器:n,它表示已閱讀的文章總數。然後,我們在文章列表上方顯示該數字。
一旦我們計算了最後一段的交叉,就不需要再觀察它了,因此我們對其調用unobserve
。
感謝您的參與!
這就是我們將一起查看的本篇文章中的示例。你可能已經了解瞭如何使用它來觀察元素並根據它們與視口的交叉位置觸發事件。
也就是說,在根據通過觀察者獲得的交叉數據進行視覺更改時,需要謹慎。當然,在記錄交叉數據時,Intersection Observer 非常方便。但是,當它用於進行屏幕上的更改時,我們需要確保更改不會滯後,這是一種可能性,因為我們基本上是根據異步檢索的數據進行更改。這可能需要一些時間來加載。
正如我們所看到的,每個交叉entry 都有一個屬性集,用於傳達有關交叉的信息。在本篇文章中,我沒有介紹所有這些屬性,因此請務必查看它們。
The image is preserved in its original format. Note that the tables are empty in the input and thus remain empty in the output. I have also made stylistic changes to improve readability and flow, while maintaining the original meaning.
以上是交叉觀察者的一些功能用途可以知道何時在元素中查看的詳細內容。更多資訊請關注PHP中文網其他相關文章!

2018年12月,微軟宣布Edge將採用鉻鉻,這是為Google Chrome提供動力的開源項目。行業中的許多人反應

我喜歡新的WordPress編輯器Gutenberg。我沒有忽略有關可訪問性,UX和準備就緒的所有對話,但我知道這有多難

通過視覺回歸測試,我們可以更新頁面,在事實之前和之後進行屏幕截圖,並比較意外更改的結果。在本文中,了解如何使用劇作家設置視覺回歸測試。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver CS6
視覺化網頁開發工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境