JavaScript 的 Intersection Observer API 應用

程式技術

最近在 iThome 看到一篇文章。

GitHub 揭露讓自家首頁飛快的開發秘訣

文章中有說明 Github 是如何在自家首頁中實作「當畫面滾動到某個位置時,就會出現對應的動畫特效」。

小弟的前端技術還在努力中,但看到這一段還是讓我眼睛為之一亮。

因為我好像在哪邊有用過 Intersection Observer API。

在小弟的部落格中,文章頁面只要一往下滾,就會在右下角出現「返回頂部」的按鈕。方便用戶閱讀文章時,可以立即回到網頁的最上方。

2021_07_14_19_35_44_60eecc10be836.png
很多網站都會有類似的功能

在過去,如果要達到上述的功能,我們可以監聽 Scroll 事件。只要一監聽到滑鼠往下滾,就可以讓「返回頂部」的按鈕顯示。

但就如 iThome 那篇文章中所提到的。當用戶在滾動的時候,就會不停的觸發 Scroll 事件,因此會耗費不少的資源。其實這樣的場景,我們可以考慮使用 Intersection Observer API 來處理。

Intersection Observer API 可以去觀察一個元素是否出現在瀏覽器窗口中。此 API 不需要事件處理器 (Event handler),而且由於是異步 (Asynchronous) 的,監聽元素是否在瀏覽器窗口中並非在主線程 (Main thread) 中執行,因此可以獲得不少的效能提升。

以部落格的移至頂部按鈕為例。首先在畫面上增加一個按鈕。

<button id="scroll-to-top-btn" title="Go to top" class="d-none">
    返回頂部
</button>

新增一個 scroll-to-top-btn.js 去監聽按鈕。

// 取得返回頂部的按鈕
let scrollToTopButton = document.getElementById('scroll-to-top-btn');
scrollToTopButton.addEventListener('click', scrollToTop);

// 滾動到網頁的最上面
function scrollToTop() {
    document.body.scrollTop = 0;
    document.documentElement.scrollTop = 0;
}

// 根據 header 是否出現在畫面上調整按鈕的樣式
let headerObserver = new IntersectionObserver(
    function(entries) {
        // 當 isIntersecting 為 true,代表此元素與瀏覽窗口是重疊的,意即元素有出現在畫面上
        if (entries[0].isIntersecting === true) {
            // 在 class 中加入 d-none
            scrollToTopButton.classList.add('d-none');
        } else {
            // 移除 class 中的 d-none
            scrollToTopButton.classList.remove('d-none');
        }
    },
    { threshold: [0] }
);

// 取得 header
// 開始監聽
headerObserver.observe(document.getElementById('header'));

// 當不再需要監聽器時,可以將其移除。節省記憶體
headerObserver.disconnect();

這樣當 header 一消失在畫面上,返回頂部的按鈕就會出現在畫面上。

除了這種應用,Intersection Observer API 還能實現。

  • 惰性加載:只有到對應的位置時才會開始載入圖片,節省網路頻寬。
  • 無限滾動:滾動到底部時載入新的資料。

參考資料

sharkHead
written by
sharkHead

後端打工仔,在下班後喜歡研究各種不同的技術。稍微擅長 PHP,並偶爾涉獵前端開發。個性就像動態語言般隨興,但渴望做事能像囉嗦的靜態語言那樣嚴謹。

0 則留言
新增留言
編輯留言