直接与委托 – 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)
可能不起作用:
- 绑定元素不是永久的 。 它是在调用
.on()
之后创build的 - 所选元素不是绑定元素的适当子元素。 这是相同的元素。
- 所选元素通过调用
.stopPropagation()
来防止事件向绑定元素冒泡 。
(省略棘手的原因,如拼写错误的select器。)