事件代表团

事件委托是一个允许我们避免向特定节点添加事件监听器的过程; 相反,事件侦听器被添加到父节点。此机制利用事件传播/冒泡来处理 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 内,因为我们只为所有元素声明了一个函数,所以内存消耗也较少。