我在网上的一篇文章中读到了这句话:
向1000个单元格中的每一个添加事件处理程序将是一个主要问题 性能问题,可能是浏览器崩溃的根源 内存泄漏。
但我不明白。例如,我正在做这样的事情:
const handler = e => // do something
document.querySelectorAll("td").forEach(td => {
td.addEventListener("click", handler);
});
我不创建1000个函数,它们都使用相同的引用,所以我缺少什么?有什么问题?
答案 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
上的所有事件处理程序都将触发,tr
和table
上的 等等,所有走上链条。
文章告诉您在table
(例如)而不是每个td
元素上注册活动。
我不创建1000个函数,它们都使用相同的引用,所以 我错过了什么?有什么问题?
您没有创建1000个函数,但是您正在注册1000个事件处理程序,这是文章建议的内容。在某些父元素上注册一个事件处理程序,例如table
。
以下是关于如何为1000个表格单元格注册一个事件处理程序的jsFiddle example。
答案 3 :(得分:1)
也许类比会帮助你更好地理解它。假设您有一家公司,客户给您打电话,并向您发送一些信息。
使用单条电话线可以提高员工的工作效率。