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

cir*_*ube 2 javascript jquery javascript-events

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

<div class="wrap">
 <button>Click me</button>
</div>
Run Code Online (Sandbox Code Playgroud)

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');
  });
});
Run Code Online (Sandbox Code Playgroud)

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

use*_*654 5

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

$('button').on('click', function(event){
    event.stopPropagation();
    ...
Run Code Online (Sandbox Code Playgroud)

时间线:

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