直接与委托 - jQuery .on()

发布于 2024-12-15 08:49:40 字数 789 浏览 2 评论 0 原文

我试图使用 直接和委托事件处理程序之间的特殊区别="noreferrer">jQuery .on() 方法。具体来说,本段最后一句:

当提供选择器时,事件处理程序被称为委托。当事件直接发生在绑定元素上时,不会调用处理程序,而是仅针对与选择器匹配的后代(内部元素)调用处理程序。 jQuery 将事件从事件目标冒泡到附加处理程序的元素(即,最内层到最外层元素),并为沿该路径匹配选择器的任何元素运行处理程序。

“运行任何元素的处理程序”是什么意思?我制作了一个测试页面来试验这个概念。但是以下两种构造都会导致相同的行为:

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

或者,

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

也许有人可以参考不同的示例来澄清这一点?谢谢。

I am trying to understand this particular difference between the direct and delegated event handlers using the jQuery .on() method. Specifically, the last sentence in this paragraph:

When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.

What does it mean by "runs the handler for any elements"? I made a test page to experiment with the concept. But both following constructs lead to the same behavior:

$("div#target span.green").on("click", function() {
   alert($(this).attr("class") + " is clicked");
});

or,

$("div#target").on("click", "span.green", function() {
   alert($(this).attr("class") + " is clicked");
});

Maybe someone could refer to a different example to clarify this point? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

无所的.畏惧 2024-12-22 08:49:41

与OP无关,但帮助我解决此功能的困惑的概念是绑定元素必须是所选元素的父元素

  • Bound 指的是.on 剩下的部分。
  • Selected 指的是 .on() 的第二个参数。

委托不像 .find() 那样工作,选择绑定元素的子集。选择器仅适用于严格的子元素。

$("span.green").on("click", ...

特别是

$("span").on("click", ".green", ...

,为了获得 @N3dst4 暗示的“将来创建的元素”的优势,绑定元素必须是永久父级。然后选定的孩子就可以来去。

编辑

为什么委托 .on 不起作用的清单

$('.bound').on('event', '.selected', some_function) 可能的棘手原因不起作用:

  1. 绑定元素不是永久。它是在调用 .on() 后创建的。
  2. 所选元素不是绑定元素的正确。这是同一个元素。
  3. 选定元素通过调用 .stopPropagation() 阻止事件冒泡到绑定元素。

(省略不太棘手的原因,例如拼写错误的选择器。)

Tangential to the OP, but the concept that helped me unravel confusion with this feature is that the bound elements must be parents of the selected elements.

  • Bound refers to what is left of the .on.
  • Selected refers to the 2nd argument of .on().

Delegation does not work like .find(), selecting a subset of the bound elements. The selector only applies to strict child elements.

$("span.green").on("click", ...

is very different from

$("span").on("click", ".green", ...

In particular, to gain the advantages @N3dst4 hints at with "elements that are created in future" the bound element must be a permanent parent. Then the selected children can come and go.

EDIT

Checklist of why delegated .on doesn't work

Tricky reasons why $('.bound').on('event', '.selected', some_function) may not work:

  1. Bound element is not permanent. It was created after calling .on()
  2. Selected element is not a proper child of a bound element. It's the same element.
  3. Selected element prevented bubbling of an event to the bound element by calling .stopPropagation().

(Omitting less tricky reasons, such as a misspelled selector.)

浅忆流年 2024-12-22 08:49:41

我写了一篇文章,对直接事件和委托事件进行了比较。我比较的是纯js,但它对于jquery具有相同的含义,只是封装了它。

结论是,委托事件处理适用于动态 DOM 结构,其中可以在用户与页面交互时创建绑定元素(不需要再次绑定),而直接事件处理适用于静态 DOM 元素,当我们知道结构不会改变时。

欲了解更多信息和完整比较 -
http://maciejsikora.com/standard-events-vs-event-delegation/< /a>

使用始终委托的处理程序,我认为这是当前非常流行的方法,这不是正确的方法,许多程序员使用它是因为“应该使用它”,但事实是直接事件处理程序更适合某些情况和选择哪种方法的使用应该得到差异知识的支持。

I wro te a post with a comparison of direct events and delegated. I compare pure js but it has the same meaning for jquery which only encapsulate it.

Conclusion is that delegated event handling is for dynamic DOM structure where binded elements can be created while user interact with page ( no need again bindings ), and direct event handling is for static DOM elements, when we know that structure will not change.

For more information and full comparison -
http://maciejsikora.com/standard-events-vs-event-delegation/

Using always delegated handlers, which I see is current very trendy is not right way, many programmers use it because "it should be used", but truth is that direct event handlers are better for some situation and the choice which method use should be supported by knowledge of differences.

陈独秀 2024-12-22 08:49:41

案例3(委托):

$("div#target").delegate("span.green", "click", function() {...});

Case 3 (delegated):

$("div#target").delegate("span.green", "click", function() {...});
生生漫 2024-12-22 08:49:40

案例 1(直接):

$("div#target span.green").on("click", function() {...});

== 嘿!我希望 div#target 中的每个 span.green 都能监听:当您被点击时,执行 X。

案例 2(委托):

$("div#target").on("click", "span.green", function() {...});

== 嘿,div#target!当您的任何“span.green”子元素被单击时,对它们执行 X 操作。

换句话说...

在情况 1 中,每个跨度都已单独给出指令。如果创建新的跨度,他们将不会听到指令,也不会响应点击。每个跨度都直接负责自己的事件。

在情况2中,仅向容器发出指示;它负责代表其子元素注意到点击。捕获事件的工作已被委派。这也意味着将对将来创建的子元素执行该指令。

Case 1 (direct):

$("div#target span.green").on("click", function() {...});

== Hey! I want every span.green inside div#target to listen up: when you get clicked on, do X.

Case 2 (delegated):

$("div#target").on("click", "span.green", function() {...});

== Hey, div#target! When any of your child elements which are "span.green" get clicked, do X with them.

In other words...

In case 1, each of those spans has been individually given instructions. If new spans get created, they won't have heard the instruction and won't respond to clicks. Each span is directly responsible for its own events.

In case 2, only the container has been given the instruction; it is responsible for noticing clicks on behalf of its child elements. The work of catching events has been delegated. This also means that the instruction will be carried out for child elements that are created in future.

东风软 2024-12-22 08:49:40

第一种方式 $("div#target span.green").on() 将点击处理程序直接绑定到在执行代码时与选择器匹配的范围。这意味着如果稍后添加其他跨度(或者更改其类以匹配),它们就会错过并且不会有单击处理程序。这也意味着如果您稍后从其中一个跨度中删除“绿色”类,其单击处理程序将继续运行 - jQuery 不会跟踪处理程序的分配方式并检查选择器是否仍然匹配。

第二种方式,$("div#target").on(),将点击处理程序绑定到匹配的 div(同样,这与当时匹配的 div 相对应),但是,当在 div 中的某处发生单击时,只有当单击不仅发生在 div 中,而且发生在与第二个参数中的选择器与 .on() 匹配的子元素中时,处理程序函数才会运行, “跨度.绿色”。通过这种方式,这些子跨度何时创建并不重要,单击它们仍然会运行处理程序。

因此,对于不动态添加或更改其内容的页面,您不会注意到这两种方法之间的差异。如果您要动态添加额外的子元素,则第二种语法意味着您不必担心为它们分配点击处理程序,因为您已经在父元素上完成过一次。

The first way, $("div#target span.green").on(), binds a click handler directly to the span(s) that match the selector at the moment that code is executed. This means if other spans are added later (or have their class changed to match) they have missed out and will not have a click handler. It also means if you later remove the "green" class from one of the spans its click handler will continue to run - jQuery doesn't keep track of how the handler was assigned and check to see if the selector still matches.

The second way, $("div#target").on(), binds a click handler to the div(s) that match (again, this is against those that match at that moment), but when a click occurs somewhere in the div the handler function will only be run if the click occurred not just in the div but in a child element matching the selector in the second parameter to .on(), "span.green". Done this way it doesn't matter when those child spans were created, clicking upon them will still run the handler.

So for a page that isn't dynamically adding or changing its contents you won't notice a difference between the two methods. If you are dynamically adding extra child elements the second syntax means you don't have to worry about assigning click handlers to them because you've already done it once on the parent.

小霸王臭丫头 2024-12-22 08:49:40

N3dst4的解释很完美。基于此,我们可以假设所有子元素都在 body 内部,因此我们只需要使用这个:

$('body').on('click', '.element', function(){
    alert('It works!')
});

它适用于直接事件或委托事件。

The explanation of N3dst4 is perfect. Based on this, we can assume that all child elements are inside body, therefore we need use only this:

$('body').on('click', '.element', function(){
    alert('It works!')
});

It works with direct or delegate event.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文