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