在偵測到事件監聽器時

小測驗:傳遞至 addEventListener() 的第三個參數有什麼用途?

如果您認為 addEventListener() 只接受兩個參數,或者總是硬式編碼 false 的值,並且對其與...泡泡的關係有模糊的理解,請不要感到尷尬。

可設定性更高的 addEventListener()

addEventListener() 方法自網頁早期以來已歷經許多改良,其新功能是透過該第三個參數的超級版本設定。方法定義最近的變更可讓開發人員透過設定物件提供其他選項,同時在有布林值參數或未指定選項時保持向後相容。

很高興在此宣布,Chrome 55 除了支援 passive 選項 (已在 Chrome 51 中實作) 和 capture 選項 (已在 Chrome 49 中實作) 外,還支援該設定物件中的 once 選項。例如:

element.addEventListener('click', myClickHandler, {
    once: true,
    passive: true,
    capture: true
});

您可以視需求搭配使用這些選項。

自行清理車輛的好處

以上就是使用新 once 選項的語法,但這會為您帶來什麼?簡而言之,這會為您提供專為「一次性」用途設計的事件監聽器。

根據預設,事件監聽器會在第一次呼叫後持續存在,這正是某些類型的事件所需的行為,例如可多次點選的按鈕。不過,如果是用於其他用途,則不必保留事件監聽器,而且如果您有必須只執行一次的回呼,可能會導致不必要的行為。注重程式碼清潔度的開發人員一向可以選擇使用 removeEventListener() 明確清理內容,遵循以下模式:

element.addEventListener('click', function cb(event) {
    // ...one-time handling of the click event...
    event.currentTarget.removeEventListener(event.type, cb);
});

使用新 once 參數的等效程式碼會更簡潔,而且不會強制您追蹤事件名稱 (event.type,如前述範例所示) 或回呼函式的參照 (cb):

element.addEventListener('click', function(event) {
    // ...one-time handling of the click event...
}, {once: true});

清理事件處理常式也可以透過銷毀與回呼函式相關聯的範圍,提供記憶體效率,讓在該範圍內擷取的變數進行垃圾收集。以下是這類差異的一個例子:

function setUpListeners() {
    var data = ['one', 'two', '...etc.'];

    window.addEventListener('load', function() {
    doSomethingWithSomeData(data);
    // data is now part of the callback's scope.
    });
}

根據預設,即使 load 事件監聽器回呼在執行完畢後不會再使用,仍會保留在範圍內。由於 data 變數是在回呼中使用,因此會保留在範圍內,且永遠不會進行垃圾收集。不過,如果透過 once 參數移除回呼,函式本身和透過其範圍保持運作的任何項目都可能成為垃圾收集的候選項目。

瀏覽器支援

Chrome 55 以上版本、Firefox 50 以上版本,以及 Safari 技術預覽版 7 以上版本提供 once 選項的原生支援

許多 JavaScript UI 程式庫都提供方便的方法,可用來建立事件監聽器,其中有些程式庫提供捷徑,可用來定義一次性事件,其中最值得注意的是 jQuery 的 one() 方法。您也可以使用 Andrea Giammarchidom4 程式庫中的 polyfill。

謝謝

感謝 Ingvar Stepanyan 針對本篇文章中的程式碼範例提供意見回饋