延遲工作,直到捲動結束

網頁功能: scrollend

在網頁上捲動時,畫面應流暢且反應靈敏。在捲動期間執行繁重工作 (例如重新計算版面配置、追蹤數據分析資料信標,或動態 DOM 更新),可能會導致主執行緒飽和,進而造成影格遺失和版面配置抖動。

過去,開發人員會使用 setTimeout() 去除 scroll 事件的彈跳,藉此猜測捲動何時結束。不過,這些去抖動函式向來不可靠。使用者還在捲動時,可能就會觸發。

scrollend 事件是高度可靠、以成效為導向的解決方案。當捲動停止、所有轉場效果完成,且觸控手勢釋放時,瀏覽器會觸發 scrollend 事件。

導入方式

如要實作延遲工作模式,請按照下列步驟操作:

  1. 設定可捲動的容器:使用 overflow: auto 或 overflow: scroll 建立容器。
  2. 監聽 scroll 事件:這個監聽器僅適用於基本動態指標或資訊版面配置樣式。請勿在此執行繁重的工作。
  3. 監聽 scrollend 事件:在捲動容器或文件本身註冊 scrollend 回呼。
  4. 在回呼中執行耗費資源的工作:在這個階段,您可以安全地擷取動態內容或觸發完整的 DOM 版面配置。

程式碼範例

.scroll-container {
  height: 300px;
  overflow-y: auto;
}
const scroller = document.querySelector('.scroll-container');

// 1. Informative feedback during scroll
scroller.addEventListener('scroll', () => {
  // Avoid dynamic heavier data updates here
  console.log('Scrolling dynamically... updates deferred');
});

// 2. Safe callback when scrolling rests
scroller.addEventListener('scrollend', () => {
  // Run layout recalculations or analytical beacons updates here
  const currentVisibleSection = findMostVisibleSection(scroller);
  fetchAdditionalData(currentVisibleSection);
});

策略執行與最佳做法

  • 務必使用 scrollend,而非去抖動的 scroll 事件,來觸發版面配置資料信標或動態擷取新內容版面配置。
  • 建議:建構輪轉介面或推薦圖庫投影片時,可搭配 scrollSnapChange 或 scrollSnapChanging 貼齊互動。
  • 請勿在動態視覺捲動回呼中,綁定與版面配置相關的動態更新。
  • 務必考量視覺可視區域縮放和捲動是否能正確觸發 scrollend 事件。

備用策略

對於不支援的瀏覽器,請改用 setTimeout 的去抖動 scroll 事件,調度自訂 scrollend 事件。

function initializeDemo() {
  const scroller = document.querySelector('#scroller');
  scroller.addEventListener('scrollend', () => {
    // Safe execution
  });
}

if ('onscrollend' in window) {
  initializeDemo();
} else {
  initializeDemo();
  const scroller = document.querySelector('#scroller');
  scroller.addEventListener('scroll', () => {
    clearTimeout(window.scrollendtimer);
    window.scrollendtimer = setTimeout(() => {
      scroller.dispatchEvent(new CustomEvent('scrollend'));
    }, 100);
  });
}