gpt4 book ai didi

javascript - 为什么不将 Javascript 事件委托(delegate)发挥到极致呢?

转载 作者:行者123 更新时间:2023-12-03 13:25:28 24 4
gpt4 key购买 nike

到目前为止,该网站上的大多数人可能都知道:

$("#someTable TD.foo").click(function(){
$(e.target).doSomething();
});

将表现得比:
$("#someTable").click(function(){
if (!$(e.target).is("TD.foo")) return;
$(e.target).doSomething();
});

现在,更糟的程度当然取决于您的 table 有多少 TD,但只要您至少有几个 TD,这个一般原则就应该适用。 (注意:当然,聪明的做法是使用 jQuery 委托(delegate)而不是上面的,但我只是想举一个明显不同的例子)。

无论如何,我向一位同事解释了这个原则,他们的回答是“好吧,对于站点范围的组件(例如,选择日期的 INPUT)为什么要停在那里?为什么不只为每种类型的组件绑定(bind)一个处理程序到 body 本身?”我没有一个好的答案。

显然,使用委托(delegate)策略意味着重新考虑如何阻止事件,所以这是一个缺点。此外,假设您可能有一个页面,其中您有一个“TD.foo”,它不应该有一个事件连接到它。但是,如果您了解并愿意解决事件冒泡更改,并且如果您执行“如果您将 .foo 放在 TD 上,它总是会连接事件”的政策,那么这些似乎都不像大不了。

我觉得我必须遗漏一些东西,所以我的问题是:将所有站点范围组件的所有事件委托(delegate)给 BODY 是否还有其他缺点(而不是将它们直接绑定(bind)到所涉及的 HTML 元素,或委托(delegate)它们到非 BODY 父元素)?

最佳答案

你缺少的是表演的不同元素。

您的第一个示例在设置点击处理程序时表现更差,但在触发实际事件时表现更好。

您的第二个示例在设置单击处理程序时表现更好,但在触发实际事件时表现明显更差。

如果所有事件都放在顶级对象(如文档)上,那么您将有一个巨大的选择器列表来检查每个事件,以便找到它与哪个处理函数一起使用。这个问题就是 jQuery 弃用 .live() 的原因。方法,因为它会查找文档对象上的所有事件以及何时有很多 .live()注册了事件处理程序后,每个事件的性能都很差,因为它必须将每个事件与大量选择器进行比较,才能为该事件找到合适的事件处理程序。对于大规模工作,将事件绑定(bind)到接近触发事件的实际对象会更有效。如果对象不是动态的,则将事件权限绑定(bind)到将触发它的对象。当您第一次绑定(bind)事件时,这可能会花费更多的 CPU,但实际的事件触发会很快并且会扩展。

jQuery的.on().delegate()可以用于此,但建议您找到尽可能接近触发对象的祖先对象。这可以防止在一个顶级对象上累积大量动态事件,并防止事件处理的性能下降。

在上面的示例中,这样做是完全合理的:

$("#someTable").on('click', "td.foo", function(e) {
$(e.target).doSomething();
});

这将为您提供所有行的单击处理程序的一个紧凑表示,即使您添加/删除行,它也会继续工作。

但是,这没有多大意义:
$(document).on('click', "#someTable td.foo", function(e) {
$(e.target).doSomething();
});

因为当没有真正需要这样做时,这会将表格事件与页面中的所有其他顶级事件混合在一起。您只要求事件处理中的性能问题,而没有处理那里的事件的任何好处。

因此,我认为对您的问题的简短回答是,在触发事件时在一个顶级位置处理所有事件会导致性能问题,因为当有很多事件发生时,代码必须理清哪个处理程序应该获取事件在同一个地方处理。处理尽可能接近生成对象的事件使事件处理更有效。

关于javascript - 为什么不将 Javascript 事件委托(delegate)发挥到极致呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9711118/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com