父级上的事件,单击子级(事件冒泡)

rdo*_*720 2 javascript jquery jquery-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>
Run Code Online (Sandbox Code Playgroud)

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

我发现我可以使用类似的东西:

$('#peopleResults').on('click', '.person', function(){
    // handle the click
})
Run Code Online (Sandbox Code Playgroud)

但我想更多地了解如何在普通 JavaScript 中处理这个问题。我认为,当通过单击事件单击某个项目的子项时,该事件会在元素中“冒泡”,并且当它击中 .person 元素时我可以捕获它。请原谅草率的代码,但类似:

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

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

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

这似乎是一些基本的东西,但我却没有想到。JavaScript 中处理这个问题的典型方法是什么?

Ori*_*iol 6

您可以为所需目标的所有子项设置pointer-events为:none

.person > * {
  pointer-events: none;
}
Run Code Online (Sandbox Code Playgroud)

这种方式event.target将是一个.person元素而不是它的后代之一。

.person > * {
  pointer-events: none;
}
Run Code Online (Sandbox Code Playgroud)
document.getElementById('peopleResults').addEventListener('click', function(e){
  if(e.target.classList.contains('person')) {
    alert('Person clicked');
  }
});
Run Code Online (Sandbox Code Playgroud)
.person > * {
  pointer-events: none;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这种方法会破坏 .txt 内的交互元素(例如链接)的功能.person