刪除逾時函式並擺脫錯誤,您真正需要的事件是 scrollend。
在 scrollend 事件之前,沒有可靠的方法可偵測捲動是否完成。這表示事件會延遲觸發,或在使用者手指仍按住螢幕時觸發。無法準確判斷捲動何時結束,導致發生錯誤,使用者體驗不佳。
document.onscroll = event => { clearTimeout(window.scrollEndTimer) window.scrollEndTimer = setTimeout(callback, 100) }
這項 setTimeout() 策略只能判斷 100ms 是否已停止捲動。因此,這比較像是捲動已暫停事件,而非捲動已結束事件。
scrollend
事件發生後,瀏覽器會為您完成所有困難的評估作業。
document.onscrollend = event => {…}
這就是好東西。在發出前,完美地計時並填入有意義的條件。
試試看!
活動詳細資料
在下列情況下,系統會觸發 scrollend 事件:
- 瀏覽器不再動畫化或轉譯捲動。
- 使用者已放開觸控。
- 使用者的指標已放開捲動滑桿。
- 使用者已放開按鍵。
- Scroll to fragment has completed.
- Scroll snap has completed.
- scrollTo() 已完成。
- 使用者已捲動視覺可視區域。
在下列情況下,不會觸發 scrollend 事件:
- 使用者的手勢未導致任何捲動位置變更 (未發生平移)。
-「scrollTo()」未產生任何翻譯結果。
這個事件之所以遲遲未在網頁平台上推出,是因為有許多細節需要詳細規格。其中一個最複雜的領域,是清楚說明視覺檢視區塊與文件之間的 scrollend 詳細資料。以網頁的放大檢視為例,處於這種縮放狀態時,您可以捲動畫面,但這不一定會捲動文件。請放心,即使是這種由使用者驅動的視覺檢視區塊捲動互動,完成後也會發出 scrollend 事件。
使用事件
與其他捲動事件一樣,您可以透過幾種方式註冊監聽器。
addEventListener("scrollend", (event) => {
// scroll ended
});
aScrollingElement.addEventListener("scrollend", (event) => {
// scroll ended
});
或使用活動屬性:
document.onscrollend = (event) => {
// scroll ended
};
aScrollingElement.onscrollend = (event) => {
// scroll ended
};
Polyfill 和漸進增強
如果您想立即使用這項新事件,建議您採取下列做法。您可以繼續使用目前的捲動結束策略 (如有),並在開頭檢查支援情況:
'onscrollend' in window
// true, if available
這會根據瀏覽器是否提供事件回報 true 或 false。透過這項檢查,您可以分支程式碼:
if ('onscrollend' in window) {
document.onscrollend = callback
}
else {
document.onscroll = event => {
clearTimeout(window.scrollEndTimer)
window.scrollEndTimer = setTimeout(callback, 100)
}
}
這樣一來,您就能在 scrollend 事件推出時,逐步改善事件。您也可以試試我製作的
polyfill
(NPM),盡可能讓瀏覽器發揮最佳效能:
import {scrollend} from "scrollyfills"
// then use scrollend as if it's existed this whole time
document.onscrollend = callback
如果瀏覽器內建 scrollend 事件,這個 Polyfill 會逐步強化,以便使用該事件。如果無法使用,指令碼會監看指標事件和捲動,盡可能估算事件的結束時間。
用途
建議您在捲動時避免執行需要大量運算資源的工作。這項做法可確保捲動功能能盡量使用記憶體和處理資源,維持流暢體驗。使用 scrollend 事件是呼叫及執行繁重工作的絕佳時機,因為捲動動作已停止。
scrollend 事件可用於觸發各種動作。常見用途是將相關聯的 UI 元素與捲動停止的位置同步。例如:
- 將輪轉介面的捲動位置與點指標同步。
- 將圖片庫項目與中繼資料同步。- 使用者捲動至新分頁後擷取資料。
舉例來說,假設使用者滑動手勢刪除電子郵件,使用者完成滑動後,您即可根據他們捲動到的位置執行動作。
您也可以在程式輔助或使用者捲動後,使用這個事件進行同步處理,或執行記錄 Analytics 等動作。
以下是根據捲動位置更新箭頭、點和焦點等多個元素的絕佳範例。在 YouTube 上觀看我如何建構這個輪轉介面。此外,您也可以試用即時示範。
感謝 Mehdi Kazemi 在這方面投入的工程工作,以及 Robert Flack 提供的 API 和實作指南。