事件代表團

事件委託是一個允許我們避免向特定節點新增事件監聽器的過程; 相反,事件偵聽器被新增到父節點。此機制利用事件傳播/冒泡來處理 DOM 中更高階元素/節點處的事件,而不是使用發起事件的元素。例如,我們需要為以下列表元素新增事件:

<ul id="container">
    <li id="item-1" class="new">Item 1</li>
    <li id="item-2">Item 2</li>
    <li id="item-3">Item 3</li>
</ul>

我們需要新增 click 處理程式,基本上,我們可以使用迴圈向每個元素新增偵聽器,但想象一下,我們想要動態新增元素。因此,我們在載入 DOM 時註冊所有事件處理程式,並且在 DOM 初始化並註冊每個元素的所有事件處理程式之後,上面的 UL 中新插入的元素將不會響應 click,因為 DOM 中不存在該元素當我們註冊了 click 事件監聽器時。

因此,為了克服這個問題,我們可以利用事件委託。這意味著,我們可以將事件監聽器繫結到它的父 UL 元素,而不是將監聽器註冊到每個 li 元素本身,例如:

document.getElementById("container").addEventListener("click", function(e) {
    console.log("List item " e.target.id, " was clicked!");
});

因為,事件預設傳播(氣泡向上),然後點選任何 LI 元素將使 UL 元素也觸發相同的事件。在這種情況下,我們可以在函式中使用 e 引數,該引數實際上是事件物件,它包含有關事件的有用資訊,包括啟動事件的原始元素。因此,例如,我們可以使用以下內容:

document.getElementById("container").addEventListener("click", function(e) {

    // If UL itself then no action is require
    if(e.target.nodeName == 'UL') return false;

    if(e.target.classList.contains('new')) {
        console.log("List item " e.target.id, " was clicked and it's new!");
    }
});

因此,顯而易見的是,e(事件物件)允許我們檢查源元素(e.target),並且我們可以在載入 DOM 之後輕鬆地向 UL 注入新元素,並且唯一一個委託事件處理程式將處理所有點選事件在父節點 UL 內,因為我們只為所有元素宣告瞭一個函式,所以記憶體消耗也較少。