我想对 jfriend00 的回答添加一些评论和反驳。 (主要是基于我的直觉我的意见)
不 - 您不应该将所有委托的事件处理程序绑定到文档
目的。这可能是您可能遇到的最糟糕的情况
创建。
首先,事件委托并不总是让您的代码更快。在
在某些情况下,这是有利的,在某些情况下则不是。你应该使用
事件委托,当你真正需要事件委托时,当你
从中受益。否则,您应该将事件处理程序直接绑定到
事件发生的对象,因为这通常会更多
高效。
虽然如果您只为单个元素注册和事件,性能可能会稍好一些,但我相信它并不能与委托带来的可扩展性优势相提并论。我也相信浏览器(将会)越来越有效地处理这个问题,尽管我没有证据证明这一点。在我看来,事件委托是要走的路!
其次,您不应该在文档中绑定所有委托事件
等级。这正是 .live() 被弃用的原因,因为这非常
当您有很多以这种方式绑定的事件时效率低下。对于委派
事件处理将它们绑定到最近的事件会更有效
不是动态的父级。
我有点同意这一点。如果您 100% 确定事件只会发生在容器内,那么将事件绑定到该容器是有意义的,但我仍然反对直接将事件绑定到触发元素。
第三,并非所有事件都有效或所有问题都可以解决
代表团。例如,如果你想拦截一个关键事件
输入控制和阻止无效键被输入到输入
控制,你不能通过委托事件处理来做到这一点,因为
事件冒泡到委托处理程序的时间,它已经
已被输入控件处理,影响已来不及
这种行为。
这根本不是真的。请看这个codePen:https://codepen.io/pwkip/pen/jObGmjq
document.addEventListener('keypress', (e) => {
e.preventDefault();
});
它说明了如何通过在文档上注册按键事件来防止用户打字。
以下是需要或有利的事件委托的时候:
当您正在捕获事件的对象是动态的
创建/删除,您仍然想在它们上捕获事件而不
每次创建新的时都必须显式地重新绑定事件处理程序
一。当您有很多对象都想要完全相同的事件时
处理程序(手数至少为数百)。在这种情况下,它可能是
在设置时更有效地绑定一个委托事件处理程序
而不是数百或更多的直接事件处理程序。 注意,委托
事件处理在运行时总是比直接事件效率低
处理程序。
我想回复https://ehsangazar.com/optimizing-javascript-event-listeners-for-performance-e28406ad406c的这句话
Event delegation promotes binding as few DOM event handlers as possible, since each event handler requires memory. For example, let’s say that we have an HTML unordered list we want to bind event handlers to. Instead of binding a click event handler for each list item (which may be hundreds for all we know), we bind one click handler to the parent unordered list itself.
此外,谷歌搜索 performance cost of event delegation google 会返回更多有利于事件委托的结果。
当您尝试捕获时(在文档中的更高级别)
文档中任何元素上发生的事件。当你的设计是
显式使用事件冒泡和 stopPropagation() 来解决一些问题
页面中的问题或功能。为了进一步理解这一点,一个
需要了解 jQuery 委托事件处理程序是如何工作的。当你
像这样调用:
$("#myParent").on('click', 'button.actionButton', myFn);它安装了一个
#myParent 对象上的通用 jQuery 事件处理程序。当点击
事件冒泡到这个委托的事件处理程序,jQuery 必须去
通过附加到此对象的委托事件处理程序列表
并查看事件的原始元素是否匹配任何
委托事件处理程序中的选择器。
因为选择器可以相当多地涉及,这意味着 jQuery 有
解析每个选择器,然后将其与
原始事件目标以查看它是否匹配每个选择器。这是
不是便宜的手术。如果只有其中一个也没什么大不了的
但是如果你把所有的选择器放在文档对象上
有数百个选择器可以与每个冒泡事件进行比较,
这会严重影响事件处理性能。
因此,您希望设置委托的事件处理程序,以便
委托事件处理程序尽可能接近目标对象。
这意味着更少的事件将通过每个委托事件冒泡
处理程序,从而提高性能。放置所有委托的事件
在文档对象上是最差的性能,因为所有
冒泡事件必须经过所有委托的事件处理程序并获得
针对所有可能的委托事件选择器进行评估。这是
究竟为什么 .live() 被弃用,因为这是 .live() 所做的并且
它被证明是非常低效的。
这在哪里记录?如果这是真的,那么 jQuery 似乎以一种非常低效的方式处理委托,那么我的反驳应该只适用于 vanilla JS。
Still:我想找到支持这一说法的官方消息来源。
:: 编辑 ::
似乎 jQuery 确实在以一种非常低效的方式进行事件冒泡(因为它们支持 IE8)
https://api.jquery.com/on/#event-performance
所以我在这里的大部分论点只适用于 vanilla JS 和现代浏览器。