jQuery事件监听器在选择器应用之前触发?

时间:2013-08-19 18:25:28

标签: javascript jquery javascript-events

我遇到了一些事件监听器。单击一个元素时,我想为点击创建另一个元素。出于某种原因,他们都在解雇。这是代码和jsbin:http://jsbin.com/uHIyiGi/2/edit HTML

<div class="wrap">
 <button>Click me</button>
</div>

JS

$('button').on('click', function(event){
  $('body').append('<p>button clicked</p>');
  $('.wrap').addClass('clicked');

  $('body').on('click', '.clicked', function(e){
    $('body').append('<p>.clicked clicked</p>');
    $('.wrap').removeClass('clicked');
    $('body').off('click', '.clicked');
  });
});

根据我对事件监听器的理解,第二个不应该触发,直到'.clicked'元素有一个完整的点击事件(鼠标向下和鼠标向上),但它在第一次点击时触发,这意味着事件是即使元素在事件发生之后没有触发类,也会触发。我看到每次成功删除事件监听器,但在我认为应该调用之前调用它。所以,我现在真的很困惑......有什么建议吗?我希望在不久的将来我会有一张脸。

1 个答案:

答案 0 :(得分:5)

活动泡沫。单击按钮时,您将向主体添加事件。一旦按钮的事件处理程序完成(意味着,wrap现在有一个单击的类),它就会继续冒泡DOM直到它到达正文。由于正文现在有一个新的点击事件,所述事件也会被触发。然后jQuery在正文中查找与.clicked选择器匹配的元素,在它找到的任何元素上调用处理程序。要停止此操作,您可以使用setTimeout延迟将事件绑定到正文,或者在按钮的单击事件上停止传播,这样它就不会冒泡到正文。

$('button').on('click', function(event){
    event.stopPropagation();
    ...

时间轴:

    触发
  1. mousedown事件,然后在按钮
  2. 上同时发出mouseup事件
  3. 点击事件处理程序在按钮
  4. 上触发
  5. clicked类已添加到.wrap div
  6. click事件绑定到正文,委托给匹配.clicked
  7. 的元素
  8. 事件通过dom向身体冒泡
  9. 在身体上触发点击事件处理程序
  10. jQuery的click事件处理程序查找与.clicked选择器匹配的当前元素(正文)的后代的任何元素
  11. 它找到具有.wrap类的clicked div,并在该元素上调用事件处理程序。