父母的事件,点击儿童(事件冒泡)

时间:2014-12-03 15:18:07

标签: javascript jquery javascript-events

我有一个人物搜索脚本,可以在您输入时显示建议。结果的结构是松散的:

<div  id="peopleResults">
  <div class="resultHolder">
    <div data-userid="ABC123" class="person">
        <div class="name">Last, First</div>
        <div class="title">Job Title</div>
        <a class="email" href="mailto:person@company.com">person@company.com</a><span class="phone">12345</span>
    </div>
    <!-- more people... -->
  </div>
</div>

由于在您键入时人员列表会被更改,因此到目前为止我使用JQuery的live()函数自动将点击事件绑定到所有.person元素。这是不推荐使用和不好的做法,因此我尝试更新代码。

我看到我可以使用类似的东西:

$('#peopleResults').on('click', '.person', function(){
    // handle the click
})

但我想了解一下如何在vanilla javascript中处理这个问题。我想,当点击一个项目的孩子时,点击事件,该事件将#34;冒泡&#34;通过元素,我可以在它击中.person元素时捕获它。请原谅邋code的代码,但有点像:

document.getElementById('peopleResults').addEventListener('click', function(e){
    if(e.target.classList.contains('person')) {
        // handle click 
    }
});

我过去做过类似的事情,但通常都有链接。 (.person在这种情况下不能成为链接,因为它包含电子邮件链接。)

所以在这种情况下它不起作用。如果我点击.person中的.name,目标是.name。

这似乎是根本不能点击我的大脑的东西。在JavaScript中处理此问题的典型方法是什么?

2 个答案:

答案 0 :(得分:4)

您可以为所需目标的所有孩子设置pointer-eventsnone

.person > * {
  pointer-events: none;
}

这种方式event.target将是.person元素,而不是其后代之一。

document.getElementById('peopleResults').addEventListener('click', function(e){
  if(e.target.classList.contains('person')) {
    alert('Person clicked');
  }
});
.person > * {
  pointer-events: none;
}
<div  id="peopleResults">
  <div class="resultHolder">
    <div data-userid="ABC123" class="person">
      <div class="name">Last, First</div>
      <div class="title">Job Title</div>
      <a class="email" href="mailto:person@company.com">person@company.com</a><span class="phone">12345</span>
    </div>
    <!-- more people... -->
  </div>
</div>

请注意,此方法会破坏.person内的互动元素(例如链接)的功能。

答案 1 :(得分:3)

使用jQuery事件时,您将获得两个您应该熟悉的属性:

  1. target
  2. currentTarget
  3. 使用事件委托时(意味着在父元素上捕获事件)target将是最初触发事件的元素,而currentTarget将是捕获事件的元素。

    考虑以下代码示例:

    $('#peopleResults').on('click', '.person', function(e) {
        if ($(e.currentTarget).hasClass('person')) console.log('yay!');
    });
    

    P.S。 - 当不使用事件委托时,两个属性都应该指向同一个元素。

    有关currentTarget的更多信息。