Direct vs. Delegated - jQuery .on()

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

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

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

$("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

案例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中,只有容器被给予指令;它负责代表其子元素注意点击。捕获事件的工作已委派。这也意味着将对将来创建的子元素执行指令。


答案 2

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

第二种方法 , 将单击处理程序绑定到匹配的 div(同样,这是针对当时匹配的 div),但是当在 div 中的某个位置发生单击时,仅当单击不仅发生在 div 中,而且发生在与第二个参数中的选择器匹配的子元素中时,才会运行处理程序函数。 “span.green”。以这种方式完成,无论何时创建这些子范围,单击它们仍将运行处理程序。$("div#target").on().on()

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