預設讓滾輪快速捲動

Sahel Sharify
Sahel Sharify

如要改善 wheel 捲動/縮放效能,建議開發人員將 {passive: true} 選項傳遞至 addEventListener(),以將 {passive: true}mousewheel 事件監聽器註冊為被動事件監聽器wheel將事件監聽器註冊為被動事件監聽器,可讓瀏覽器不要呼叫 preventDefault(),且瀏覽器可以安全地執行捲動和縮放作業,而不會封鎖事件監聽器。

問題是,滾輪事件監聽器在概念上通常是被動地被動 (請勿呼叫 preventDefault()),但卻並未明確指定,例如需要瀏覽器等待 JS 事件處理程序完成,才會開始捲動/縮放 (即使不需要等待)。在 Chrome 56 版中,我們修正了 touchstarttouchmove 這個問題,Safari 和 Firefox 後來又採用這項變更。正如我們當時製作的示範影片所示,在捲動回應中留下明顯延遲,而留下此行為。現在,在 Chrome 73 版中,我們已將相同的介入措施套用至 wheelmousewheel 事件。

幹預

這項變動旨在縮短使用者開始透過滾輪或觸控板捲動畫面後更新顯示內容所需的時間,而開發人員不必變更程式碼。我們的指標顯示,在根目標 (視窗、文件或主體) 上註冊的 wheelmousewheel 事件監聽器中,有 75% 並未為被動選項指定任何值,且超過 98% 的事件監聽器不會呼叫 preventDefault()。在 Chrome 73 版中,我們將變更在根目標 (視窗、文件或內文) 上註冊的 wheelmousewheel 事件監聽器,預設為被動式。這表示事件監聽器如下:

window.addEventListener("wheel", func);

等於:

window.addEventListener("wheel", func, {passive: true});

如果是在事件監聽器內呼叫 preventDefault(),系統會忽略以下開發人員工具警告:

[Intervention] Unable to preventDefault inside passive event listener due
to target being treated as passive. See https://www.chromestatus.com/features/6662647093133312

故障與指引

在絕大多數情況下,我們不會觀察到任何故障。在極少數情況下 (根據我們的指標,佔不到 0.3% 的網頁),可能會發生非預期的捲動/縮放情形,這是因為系統會將 preventDefault() 呼叫忽略預設為被動的事件監聽器。應用程式會透過 defaultPrevented 屬性,檢查呼叫 preventDefault() 是否產生任何效果,藉此判斷是否要在野外發生。受影響情況的修正相當簡單:將 {passive: false} 傳遞至 addEventListener() 以覆寫預設行為,並將事件監聽器保留為封鎖。