【问题标题】:jQuery event listener fires before selector applied?jQuery 事件监听器在选择器应用之前触发?
【发布时间】:2013-08-19 18:25:28
【问题描述】:

我被一些事件监听器困住了。单击一个元素时,我想为单击创建另一个侦听器。出于某种原因,他们都在开火。这是代码和 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”元素具有完整的点击事件(鼠标按下和鼠标向上)之前,第二个不应该触发,但它会在第一次点击时触发,这意味着事件是即使元素在事件之后才具有触发器类,也会被触发。我每次都看到事件侦听器成功删除,但在我认为应该调用它之前就调用了它。所以,我现在真的很困惑......有什么建议吗?我希望我在不久的将来有一个手掌。

【问题讨论】:

标签: javascript jquery javascript-events


【解决方案1】:

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

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

时间线:

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

【讨论】:

  • 对,我得到了那个事件冒泡,但是 dpcumentation 状态:“点击事件仅在这一系列事件之后触发:当指针在元素内部时按下鼠标按钮。鼠标按钮当指针在元素内时被释放”。
  • 当点击开始时,如果选择器类不存在,为什么会触发“嵌套”事件。
  • 对,但是一旦触发了那个事件,整个事件就会冒泡。当事件到达 body 时,wrap div 将有一个 clicked 类。
  • 当事件通过冒泡到达正文时,jQuery 然后在正文中查找与.clicked 选择器匹配的元素。由于 wrap 现在具有该类,因此将在 wrap 上触发处理程序。
  • @circlecube:课程是否在mousdown上并不重要。该元素仅在单击后检查,此时它具有类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 2014-08-30
  • 1970-01-01
  • 2015-11-22
相关资源
最近更新 更多