直接与委托 – jQuery .on()

我想了解使用jQuery .on()方法 直接委托事件处理程序之间的这种特殊区别。 具体来说,这一段的最后一句话是:

当提供selector ,事件处理程序被称为委托 。 当事件直接发生在绑定元素上时,处理程序不会被调用,但是只有匹配select器的后代(内部元素)才会调用该处理程序。 jQuery将事件从事件目标拖动到处理程序所在的元素(即,最内层到最外层的元素),并沿着匹配select器的path上的任何元素运行处理程序。

这是什么意思“运行处理程序的任何元素”? 我做了一个testing页面来实验这个概念。 但是下面的结构都会导致相同的行为:

 $("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"); }); 

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

案例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中,每个跨度都被单独给出指令。 如果新的跨度被创build,他们将不会听到指令,并且不会响应点击。 每个跨度直接负责自己的事件。

在情况2中,只有容器已经被指示; 它负责代表其子元素的点击。 捕捉事件的工作已经下放 。 这也意味着这个指令将会在未来创build的子元素中执行。

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

第二种方法$("div#target").on()将点击处理程序绑定到匹配的div(同样,这是针对那些匹配的),但是当点击发生只有当点击发生不只是在div中,而是在与.on() ,“span.green”的第二个参数中的select器相匹配的子元素中,处理函数的div才会运行。 完成这种方式,当这些子跨度创build时无关紧要,点击它们仍将运行处理程序。

因此,对于不dynamic添加或更改其内容的页面,您将不会注意到这两种方法之间的区别。 如果你dynamic地添加额外的子元素,第二个语法意味着你不必担心分配处理程序给他们,因为你已经做了一次父对象。

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

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

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

我写了直接事件的比较和委托。 我比较纯js,但它只有封装它的jquery相同的意思。

结论是委托事件处理是针对dynamicDOM结构的,当用户与页面交互时(不需要再绑定),绑定元素可以被创build,直接事件处理是静态DOM元素,当我们知道结构不会改变的时候。

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

使用总是委托处理程序,我看到目前很时髦是不正确的方式,许多程序员使用它,因为“它应该使用”,但事实是,直接事件处理程序是更好的一些情况和select哪种方法使用应该支持了解差异。

与OP相切,但是帮助我解开与这个特征混淆的概念是, 绑定元素必须是所选元素的父项

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

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

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

是非常不同的

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

特别是,为了获得@ N3dst4提示“将来创build的元素”的优点,绑定元素必须是永久的父元素。 然后select的孩子可以来去。

编辑

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

为什么$('.bound').on('event', '.selected', some_function)可能不起作用:

  1. 绑定元素不是永久的 。 它是在调用.on()之后创build的
  2. 所选元素不是绑定元素的适当元素。 这是相同的元素。
  3. 所选元素通过调用.stopPropagation()来防止事件向绑定元素冒泡

(省略棘手的原因,如拼写错误的select器。)