直接与委托-jQuery. on ()

我试图理解使用 JQuery < em > . on () 方法直接授权事件处理程序之间的这种特殊区别。具体来说,本段最后一句:

当提供 selector时,事件处理程序称为 授权。当事件直接发生在绑定元素上时,不会调用该处理程序,而只对与选择器匹配的后代(内部元素)调用该处理程序。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");
});

也许有人可以引用一个不同的例子来澄清这一点? 谢谢。

45084 次浏览

第一种方法是 $("div#target span.green").on(),它将单击处理程序直接绑定到执行代码时匹配选择器的 span。这意味着,如果以后添加了其他跨(或者将其类更改为匹配) ,那么它们将错过并且不会有单击处理程序。这也意味着,如果你稍后从其中一个区域中删除“ green”类,它的 click 处理程序将继续运行—— jQuery 不会跟踪处理程序是如何分配的,并检查选择器是否仍然匹配。

第二种方法是 $("div#target").on(),它将一个 click 处理程序绑定到匹配的 div (同样,这是针对当时匹配的那些) ,但是当一个 click 发生在 div 中的某个地方时,处理程序函数只有在这个 click 不仅发生在 div 中,而且发生在与第二个参数中的选择器相匹配的子元素中时才会运行。按照这种方式创建子跨区域的时间并不重要,单击它们仍然会运行处理程序。

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

个案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中,这些跨度中的每一个都被单独地给予了指示。如果创建了新的 span,它们将不会听到指令,也不会响应单击。对于自己的事件,每个跨度都是 直接负责

在第二种情况中,只有容器得到了指令; 它负责注意到单击 代表的子元素。捕捉事件的工作一直是 授权。这也意味着将对将来创建的子元素执行指令。

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

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

它与直接或委托事件一起工作。

与 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()防止事件向绑定的元素发生 冒泡

(省略不太复杂的原因,如拼写错误的选择器。)

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

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

欲了解更多信息和进行全面比较- Http://maciejsikora.com/standard-events-vs-event-delegation/

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

个案3(获授权) :

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