JavaScript了解事件委派的必要性

时间:2017-04-07 11:47:28

标签: javascript

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

  

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

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

const handler = e => // do something

document.querySelectorAll("td").forEach(td => {
   td.addEventListener("click", handler);
});

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

4 个答案:

答案 0 :(得分:4)

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

// 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!");
    }
});

它的帮助方式是,现在,不是在每个元素上添加一个eventListner,我只需将它附加到父级,然后检查它的孩子。

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

如果将它附加到有许多孩子的父母身上,它可能会降低性能,而这些孩子实际上并不是该事件的预期节点。例如,如果你附加了身体节点本身,然后委托给了'td&#39;里面的标签!理论上它肯定会起作用,但可能会使事情变慢。

答案 1 :(得分:4)

  

我不创建1000个函数,它们都使用相同的引用,所以我缺少什么?

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

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

答案 2 :(得分:1)

在JavaScript中,事件将冒出DOM链。当您点击td时,td上的所有事件处理程序都将触发,trtable上的 等等,所有走上链条。

文章告诉您在table(例如)而不是每个td元素上注册活动。

  

我不创建1000个函数,它们都使用相同的引用,所以   我错过了什么?有什么问题?

您没有创建1000个函数,但是您正在注册1000个事件处理程序,这是文章建议的内容。在某些父元素上注册一个事件处理程序,例如table

以下是关于如何为1000个表格单元格注册一个事件处理程序的jsFiddle example

答案 3 :(得分:1)

也许类比会帮助你更好地理解它。假设您有一家公司,客户给您打电话,并向您发送一些信息。

  • 为每个小区附加一个独特的事件处理程序,希望拥有1000条电话线,每个客户一条,并且需要雇佣1000名员工来处理等待订单的每部电话。
  • 将单个事件处理程序附加到所有单元格就像仍然有1000条电话线,每个客户一条,但由一名员工监控,该员工必须弄清楚哪个客户的线路正在响铃以及在哪里发送这些内容。您不再需要1000名员工,但仍有1000条电话线。
  • 使用事件委托就像拥有一条所有客户呼叫的电话线,以及一位知道根据来电显示身份发送内容的员工。

使用单条电话线可以提高员工的工作效率。