直接与委派 - jQuery .on()

时间:2011-11-13 10:26:55

标签: javascript jquery event-bubbling jquery-events event-binding

我正在尝试使用jQuery .on() method了解直接委派事件处理程序之间的这种特殊区别。具体而言,本段最后一句:

  

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

"运行任何元素的处理程序"是什么意思?我做了test page来试验这个概念。但是以下两种结构都会导致相同的行为:

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

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

6 个答案:

答案 0 :(得分:360)

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

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:4)

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

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

适用于直接或委托活动。

答案 3 :(得分:2)

与OP相切,但帮助我解开与此功能混淆的概念是绑定元素必须是所选元素的父元素

  • 绑定是指.on的剩余部分。
  • Selected是指.on()的第二个参数。

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

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

非常不同
$("span").on("click", ".green", ...

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

修改

委派.on无效的原因核对清单

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

  1. 绑定元素不是永久。它是在调用.on()
  2. 后创建的
  3. 所选元素不是绑定元素的正确。它是相同的元素。
  4. 所选元素通过调用.stopPropagation()阻止事件的冒泡到绑定元素。
  5. (省略不太棘手的原因,例如拼写错误的选择器。)

答案 4 :(得分:1)

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

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

更多信息和完整比较 - http://maciejsikora.com/standard-events-vs-event-delegation/

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

答案 5 :(得分:0)

案例 3(委托):

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