以往我們要做偵測頁面滾動到何處時會偵測 scroll 的事件,然後透過 scroll 捲動回傳的位置再去做不一樣的事情,不過這樣變成你只要捲動就會一直回傳事件,那是否可以讓想要偵測的事件自己去判斷是否已經進入指定的範圍呢? 在現在是可以的,就是使用 Intersection Observer API。
要使用這個 API 的話有幾個步驟。
1. 建立觀察器(observer)
觀察器就是用來設定你要偵測捲動目標是否進入可見範圍的容器,會用以下方法建立:
const observer = new IntersectionObserver(callback, [option])
callback 就是當目標(target)進入/離開觀察器(root)的可見範圍會做的事。
option 是選項,都不填就會使用預設值,option 可以填的內容如下:
{ root: null, rootMargin: "0px 0px 0px 0px", threshold: [0] }
其中各項參數說明如下:
root
指定的容器,比如要偵測 #container 內的目標是否進入可見範圍,就可以像這樣設定:
root: document.getElementById('container');
預設為 null 也就是代表整個頁面(body)。
rootMargin
意思是移動到目標的相對位置,預設四邊都是 0px,如果設定 10px 的話,代表是距離目標還有 10px 時才會觸發事件,也可以設定負值,比如設定 -20px 的話,代表已經進入目標 20px 後才會觸發事件。
threshold
這個參數是設定目標進入可見範圍多少百分比後會觸發,用陣列帶入,比如:
threshold: [0, 0.25, 0.5]
就會目標出現 0%(也就是剛出現)、25% 及 50% 時都觸發事件。
2. 指定目標(entry)
就指定要觀察的目標是什麼就對了。
function callback(entry) {} let observer = new IntersectionObserver(callback); let img = document.getElementById('img'); observer.observe(img);
如果要觀察複數的目標,可以使用迴圈:
const targets = document.querySelectorAll('.box'); for (const target of targets) { observer.observe(target); }
3. 執行 callback
容器跟目標都設定好後,就可以設計 callback 要做的事了:
const callback = (entries) => { entries.forEach(entry => { if(entry.isIntersecting){ console.log("into") }else{ console.log("leave") } }); };
其中 entry.isIntersecting 會回傳進入或離開,可以判斷該值對兩個狀態做不一樣的事情。
範例程式碼:
對頁面的:
參考:
[教學] 如何用 Intersection Observer API 實作 Infinite Scroll/Lazy Loading
IntersectionObserver:上篇 – 基本介紹及使用