偵測網頁滾動或元素是否進入到畫面

前面幾週提到,當初開發專案時,用碰到視差滾動、或是滾動到某一元素時,就啟動某一個動畫效果。這邊整理一下如何偵測滾動、或是如何偵測元素是否進到畫面。

目前我知道有兩種方式:scroll 事件與 Intersection Observer 這個 Web API。

一、scroll 事件

當使用者透過輸入裝置改變網頁畫面高度時,就會觸發 scroll 事件,例如用滑鼠滾輪捲動、左鍵拖曳瀏覽器捲軸、down 方向鍵輸入等等。

可以在 .js 檔中用 (1) addEventListner 來偵測 scroll 事件。若偵測到的話,就在第二個參數傳入一個 function,接著這個 function 會自動執行。或是用 (2) onScroll 來偵測。

1
2
3
4
5
6
7
8
// 第一種
window.addEventListener('scroll', function(){
// doSomething()
})
// 第二種
window.onscroll = function() {
// doSomething()
}

IntersectionObserver Web API

先來個望詞生義。Intersection 意思是「相交處、路口」,Obersever 意思是「觀察者」。假設網頁上有幾個角色:ABC。A 是整個目前看到的畫面(viewport)、B 是在畫面外的元素(例如一張圖片) 、C 是一個只存在 JS 中且不在畫面上出現的觀察者(IntersectionObserver)。當使用者滾動畫面,B 圖片進入 A 畫面範圍時(香蕉時),C 這個觀察者接受到這個事件發生後,就會去執行某個被設定好的 function。

這是一支我沒用過也不太熟的 API,在撰文的當下其實我不會用 XD。先簡單整理幾個它常被用來處理什麼需求好了:

  1. 無限滾動,滾到底部自動載入剩下的資訊
  2. 圖片的 lazy load

爬了 w3c 的一些文,這支 API 好像是 Google 在 2016 年提出構想、在 2017 年提出草案的,目前已經有四個瀏覽器引擎實做了這支 API,分別是 Chromium、Edge、Firefox、Webkit,可以說主流的瀏覽器都支援了這支 API。

IntersectionObserver 簡單說明

假設一個情境好了,即獵人看到鏡頭中出現獵物的話就開槍。那麼偽代碼如下

1
2
3
4
5
6
7
8
// 1. 研發「開槍」技能樹
function 開槍(){}
// 2. 招募一個獵人,跟他說看到畫面中有某個東西跑出來的話就開槍,什麼東西晚點跟你說
var 獵人 = new IntersectionObserver(開槍)
// 3. 想抓的獵物是誰
var 獵物 = document.getElementById('兔兔')
// 4. 跟獵人說,看到指定的獵物就開槍
獵人.observe(獵物)

除了獵人(觀察者 observer)和獵物(目標 target) 外這兩個重要概念外,還有兩個重要概念:entry 和 option。不過這就等我之後再次遇到這個需求時再慢慢研究好了。有興趣的人可以參考相關資源。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var 獵人 = new IntersectionObserver(function 開槍(entry) {
const {
time,
rootBounds,
boundingClientRect,
intersectionRect,
intersectionRatio,
target
} = entry
// doSomething()
}, option = {
threshold,
root,
rootMargin
})

var 獵物 = document.getElementById('兔兔')
獵人.observe(獵物)

相關資源