使用 jQuery on() 时,为什么要使用(文档)而不是元素本身?

IT技术 javascript jquery html
2021-02-25 02:28:46

我希望 jQuery 专家用他们自己的话来解释为什么其他人为 jQuery 的 on() 语句推荐 $(document) 标识符而不是仅使用元素本身

示例 1:为什么在此处使用 $(document) 比示例 #2 更好?

$(document).on("click", ".areaCodeList a", function(){
    // do stuff
});

示例 2:与示例 1 相比,考虑到不好的做法,为什么以这种方式使用元素?

$(".areaCodeList a").on("click", function(){
    // do stuff
});
6个回答

这两个都是有效的。

前者适用于动态添加的元素。您使用document是因为您将事件委托给文档对象的子对象,因此事件会冒泡到文档级别。选择最接近的父级也更方便(并且在加载时父级必须存在于页面上)。

后者仍然有效,并且是将事件简单地绑定到特定元素的首选方式。

我个人不建议通过document对象进行委托,而是推荐页面加载时存在的最接近的父对象。

以下on().

是的。人们document在对功能知之甚少时使用我绝对会建议通过最亲近的父母委派。请记住,页面加载时必须存在父级但这仅用于委托给动态元素。如果只想绑定,选择要绑定的元素,按第一种方式进行。
2021-04-18 02:28:46
那么,您是否会说您不建议将事件委托给文档级别,而是委托给父级别?我对你的理解正确吗?
2021-04-22 02:28:46

这不是真的。

这两行完全是两件不同的事情。

第一个是带有选择器的委托事件,".areaCodeList a"而第二行是附加到".areaCodeList a"元素的事件

".areaCodeList a"尽管在执行该行时它在 DOM 中,但委托事件将触发每个元素。

无论如何,document根本不建议将委托事件附加到live文档中所述

由于所有 .live() 事件都附加在文档元素上,因此事件在处理之前采用最长和最慢的可能路径

请阅读on 文档

事件处理程序仅绑定到当前选定的元素;当您的代码调用 .on() 时,它们必须存在于页面上。为确保元素存在并且可以被选择,请在文档就绪处理程序中为页面上 HTML 标记中的元素执行事件绑定。如果将新 HTML 注入页面,则在将新 HTML 放入页面后选择元素并附加事件处理程序。或者,使用委托事件附加事件处理程序,如下所述。

委托事件的优点是它们可以处理来自稍后添加到文档的后代元素的事件。通过选择在附加委托事件处理程序时保证存在的元素,您可以使用委托事件来避免频繁附加和删除事件处理程序的需要。例如,如果事件处理程序想要监视文档中的所有冒泡事件,则此元素可以是模型-视图-控制器设计中视图的容器元素。在加载任何其他 HTML 之前,文档元素在文档的头部可用,因此可以安全地在那里附加事件,而无需等待文档准备就绪。
...
...

@gdoron:这不是真的,live()已被弃用。on()应始终使用,除非您有较早版本的 jQuery。即使在这种情况下,delegate()建议。
2021-04-17 02:28:46
您好,感谢您的回答。您说完全不推荐将委托事件附加到文档的理由是什么?有哪些陷阱?表现?这不是 live() 被认为是糟糕实践的原因吗?这就是我问的原因,因为我已经看到几个“堆栈”开发人员说将某些内容固定在(文档)与父元素或元素本身上是更好的做法
2021-04-20 02:28:46
@倾盆大雨046。阅读文档:Since all .live() events are attached at the document element, events take the longest and slowest possible path before they are handled因此,如果您使用on但将事件附加到文档,则可以继续使用live
2021-04-24 02:28:46
谢谢你的详细回复
2021-05-04 02:28:46
正要贴这个东西。
2021-05-10 02:28:46

我认为你混淆了几个概念。不建议绑定到文档元素,但是有时您想要这样做,例如将事件绑定到动态添加的元素时。

所有这些似乎都不清楚,所以这里是第一个示例,它直接使用类选择器并绑定单击事件,在事件绑定后稍后动态插入元素。正如你所看到的,事件永远不会被触发,因为我们选择了一个在事件绑定时不存在于 DOM 中的元素。这相当于一个.click

现在看第二个例子。在这里您可以看到我们将根元素定义为document. 这意味着单击事件将一直向上冒泡到 DOM 树,然后如果被单击的元素具有动态类,则触发。这相当于.live

现在,如果一个例子中,在结合事件的元素存在于DOM的时候,该代码会工作得很好,你可以看到在这里

话虽如此。这是文档中的一个例外,它阐明了上述行为。

事件处理程序仅绑定到当前选定的元素;当您的代码调用 .on() 时,它们必须存在于页面上

所以,总而言之。document当您确定您选择的元素没有父元素时,请使用该元素,该元素保证在绑定事件时位于 DOM 中。如果存在父元素,则使用它而不是document元素。这样事件就不必一直向上冒泡document,它只需要传播很短的距离。

感谢您补充说明
2021-05-07 02:28:46

对此没有任何“推荐”。第一个片段设置了一个“委托”事件,后者是一个“直接”事件。文档on()深入解释了这些。

当您需要侦听尚不存在的元素的事件时,委托事件是必要的 - 例如,将在 AJAX 调用之后动态创建的元素。它们有时也可以在性能方面更好 - 与 1000 个按钮相比,您需要更少的内存来将“真正的”事件处理程序附加到文档对象。

我会说,如果可以的话,仍然最好使用直接事件处理程序,或者将委托事件附加到尽可能接近真实事件源的元素。将所有事件处理程序放在文档对象上可能会降低性能 - 您必须匹配针对所有选择器触发的每个事件。如果您需要阻止事件冒泡,也可能需要它 - 如果所有事件都被捕获在文档中,那么它们已经冒泡了。

实际上的情况下的最佳解决方案,例如,这是不使用$(document)既不像的特定元件$("selector")

最好的方法是使用元素的容器并在 on 函数中绑定元素选择器。通过这样做,您可以避免不必要的事件冒泡到文档中。

所以代码应该是这样的:

$("this_is_the_container").on('event','my_element_selector',function(){
// do some stuff here
})