JavaScript 理解事件委托的需要

und*_*ned 3 javascript

我在网上的一篇文章中读到了这句话:

向 1000 个单元中的每一个添加事件处理程序将是一个主要的性能问题,并且可能是浏览器崩溃内存泄漏的来源。

但我不明白。例如,如果我正在做这样的事情:

const handler = e => // do something

document.querySelectorAll("td").forEach(td => {
   td.addEventListener("click", handler);
});
Run Code Online (Sandbox Code Playgroud)

没有创建 1000 个函数,它们都使用相同的引用,那么我缺少什么?问题是什么?

May*_*Raj 5

事件委托的工作方式是在父元素中添加一个事件侦听器。当父级触发事件时,您会获得触发事件的实际元素的引用,然后检查该元素是否是您要侦听的元素 也许代码可以帮助您更好地理解它

// Listen for the event on the parent...
document.getElementById("event-table").addEventListener("click", function(e) {
    // '.target' will now give us our actual clicked element
    if(e.target && e.target.nodeName == "td") {
        // Wooho, a '<td>' node was clicked
        console.log("We have our click event delegated!");
    }
});
Run Code Online (Sandbox Code Playgroud)

它的帮助方式是,现在无需在每个元素上添加一个 eventListner,我可以简单地将它附加到父元素,然后检查它的子元素。

这个功能的真正用途是当你想在一些动态创建的元素上附加事件时。假设您的表中的一行是在数据库调用后动态添加的。在这种情况下,如果您打算将事件附加到每个节点,则必须将事件侦听器重新附加到新节点。但是如果你使用委托方法,当事件附加到父节点时,新创建的子节点会自动成为事件的一部分

如果将其附加到具有许多子节点的父节点(实际上并不是事件的预期节点),则可能会降低性能。例如,如果您附加 body 节点本身,然后委托给其中的“td”标签!从理论上讲,它肯定会起作用,但可能会减慢速度。


Ber*_*rgi 5

我没有创建 1000 个函数,它们都使用相同的引用,那么我缺少什么?

您仍然会在 1000 个 DOM 节点中创建 1000 个函数引用。这可能看起来并不重要,但表格可能会增长......

当然,你基本上是对的,如果你不创建 1000 个闭包,就不会有那么多问题。然而,你真的有 1000 个按钮都做同样的事情吗?使用闭包,很容易让它们做稍微不同的事情;只需一个函数,您就需要使其动态依赖于单击的单元格(事件目标)。当您已经这样做时,您可以继续使用单个函数引用和事件委托......