DOM 事件委托与否,哪个是最好的资源?

DOM event delegation or not, which is best resourcewise?

上下文:

问题:

在此设置中,浏览器的资源方面(流动性、加载时间、响应能力等)最好:

  1. <table> 元素上使用单个委托点击处理程序?这将通过点击任何其他单元格或子元素来触发,并且基本上会触发很多次,但什么也没有。
  2. 在每一行的每个 <button> 上使用事件处理程序?这将添加许多处理程序,但每个处理程序只在需要时 运行 一次。
  3. 另一种选择?

浏览器本身真的有区别吗? (不考虑编码实践

在 (1) 委托情况下,浏览器是否必须为每个子元素添加一些侦听器才能知道它已被单击?

在您描述的情况下,事件委托的主要性能优势是

  1. 您只需连接一个处理程序一次,而不是遍历所有行来完成它。但是如果你有一个 table 太大以至于将处理程序连接到按钮是一个缓慢的操作,你可能会遇到其他性能问题 table.

  2. A 次要 内存节省(事件注册)。

如果它是 click 处理程序,则无需担心性能劣势。 (例如,mousemove 处理程序可能并非如此。)

需要考虑代码的复杂性和维护问题(委派的处理程序 稍微 编写起来更复杂;如果添加了按钮,则将处理程序连接到每个按钮更容易出错在某些时候动态),但您说过您主要关心的是性能。

In the (1) delegate case, doesn't the browser have to somewhat add listeners to every child element to know it has been clicked ?

不,只有一个事件侦听器。点击 bubble 会发生什么。这是旧 DOM3 events spec (I can't find this diagram or an equivalent in the now-canonical WHAT-WG DOM spec 的图表,很不幸):

处​​理程序仅附加到一个元素。当点击冒泡(传播)到该元素时会发现它。

  1. Use a single delegate click handler on the <table> element ? This would be triggered by any click on any other cell or sub-element and basically triggered many more times for just nothing.

确实如此,但无害。所需的工作量几乎为零。

  1. Use an event handler on every <button> on every row ? This would add many handlers but each would run only once when needed.

您不需要很多 处理程序,您可以为多个按钮重复使用相同的功能。这只是处理程序的多个 注册

function buttonHandler(event) {
    // ...
}
// ...
for (const btn of document.querySelectorAll(".selector-for-button")) {
    btn.addEventListener("click", buttonHandler); // Adds a registration, not
                                                  // an additional function
}

这不会为每个按钮创建新功能,它会为所有按钮重复使用相同的功能。在调用期间,event.currentTarget 将引用被单击的特定按钮(我们将处理程序连接到的按钮)。 (如果按钮有子元素,event.target 可能引用其中一个子元素,但 event.currentTarget 将引用按钮。)

因此,在任何给定情况下,您都必须权衡各种因素来决定要做什么。