使用資源
接續上一篇的 IntersectionObserver基本使用(以下簡稱IO),本篇來寫三個實際應用。
本篇用到的資源如下:
UI framewrok:Bootstrap4
css animation:animate.css
無限捲動的資料:JSONPlaceholder
lazy load 延遲載入(圖片、影片)
IO 最基本的應用就是延遲載入 lazy load 了,如果 Google 一下大部份也都是拿 lazy load 來當示範。
lazy load 的概念是這樣:
- img 的 src 不填,改填
data-src="圖片路徑"
- 當 img 的區塊出現在視窗上後,把
data-src
的值寫入到src
裡
以前對於「當img的區塊出現在視窗上」,大概就是用 onscroll
來監聽,現在有了 IO,就可以放下 onscroll 讓它成佛了。
因為概念就是 XX 區塊出現在視窗時,就替換 src,所以除了 img,也可以用成 Youtube iframe。
HTML
HTML 很簡單:
JavaScript
JS 的部份…好吧,如果 上一篇 有看,也真的很簡單 XD~ 如下:
一個神奇的狀況(坑?)
話說在寫範例的時候,遇到了一個狀況,就是 IO 的 rootMargin
這個參數。
rootMargin
,MDN 上說:
計算交叉時添加到根(root)邊界盒bounding box的矩形偏移量,可以有效的縮小或擴大根的判定範圍從而滿足計算需要。
Intersection Observer
是不是看不懂?對,August 也看不懂,原本的理解是,rootMargin 是一個可以放大、縮小觀察器的鏡頭大小的參數,比方我們的螢幕是 13 寸,但我想把觀察的範圍拉大到 15 寸,我們就在 rootMargin 上加大。
想像很美好,現實很殘酷,實際要做的時候,原本是想把鏡頭往上移螢幕大小的一半,讓 img 的部份出現在螢幕的一半時,才執行 callback。
結果,August 發現即便改便了 rootMargin,但卻一樣是 img 一出現在螢幕上,就執行 callback 了。
Google 了一下,發現也有人有遇到這問題,但還沒有人提供解答:
IntersectionObserver rootMargin’s positive and negative values are not working
這個發現 August 更新到上篇中了,懇請知道原因的大大可以在留言區中留言。
lazy load 的完整原始碼跟 Demo 會附在最後一段。
進場效果
進場效果的思考方式其實跟 lazy load 很像,不一樣的是,lazy load 是 img 出現在視窗時就替換 src。而進場效果則是區塊進入到視窗時,就把 class name 加進去。
是不是會了 IntersectionObserver,就等於會了很多功能?
HTML
本篇效果直接用 animate.css 的,就不另外手刻,因此只需要把 class name 寫在 data-animated
,然後用 JS 加進去。
JavaScript
JS 的部份跟 lazy load 很像,基本上就是 ctrl C、ctrl V 後再改個變數名(咦?)
進場效果的完整原始碼跟 Demo 會附在最後一段。
無限捲動
先聲明,August 是很不接受無限捲動這個方式的,除非你的網頁架構跟 FB、IG、Twitter 等社群一樣,架構扁平,沒有一般網站的首頁 > 列表 > 單文 這樣的層次,而且每張卡片的 HTML 都不長。
之前看過一篇,是在說明並非每個站都適合無限滾動的:
Infinite Scrolling Is Not for Every Website
但不知道為什麼,最近身邊人一窩蜂的都想要這功能,是只打算把自己的網站當作 FB 那樣消遣用的就是了。
本篇的無限滾動,是像 FB 那樣子,頁面每捲到底,就會多載入一張卡片進來。
HTML
因為實際上的卡片都是由 JS 塞進去的,所以 HTML 很單純:
分成 2 個 div,一個是要給塞卡片的,一個是觸發 IO callback 的。
JavaScript
JS 的部份,August 這邊寫最多載入 10 篇,10 篇一到就關閉 IO。
另外很有趣的是,因為 insert 新的 HTML,是 insert 在 IO 觀察的那個 div 之上,所以即便是新增了 code 進去,IO.observe
也不必再重呼一次,因為目標就一直待在頁尾的部份。
原始碼、Demo
本篇的 3 個實作項目的 Demo 在這,全部都寫在同一頁:
https://letswritetw.github.io/letswrite-intersection-observer/
原始碼的部份整理在 GitHub:
https://github.com/letswritetw/letswrite-intersection-observer


最近剛好也在看lazy loading
發現IntersectionObserver rootMargin’s positive and negative values are not working這篇有人回覆了
真的耶