单击父项的子项时的事件侦听器

时间:2019-09-29 17:37:31

标签: javascript html addeventlistener event-listener

我目前有一个问题,希望查看事件何时被点击。我想为此使用事件委托,因此我在父div上设置了一个事件侦听器,用于侦听点击:

document.querySelector('.side-nav').addEventListener('click', e => {
    console.log(e.target.data.set.param);
});

这是我的DOM:

<div class="side-nav">
    <div class="side-nav-button side-nav-active pointer" id="dashboard-shortcut" title="Home" data-page="dashboard">
        <p class="side-nav-button-icon"><i class="fas fa-home"></i></p>
    </div>
    <div class="side-nav-button side-nav-active pointer" id="another-div-shortcut" title="page2" data-page="page2">
        <p class="side-nav-button-icon"><i class="fas fa-cross"></i></p>
    </div>
</div>

我希望能够在单击右div时,即在单击div data-page时获得dashboard-shortcut属性。有什么办法可以做到这一点?

非常感谢您。

3 个答案:

答案 0 :(得分:2)

除非您希望动态添加元素,否则不要使用事件委托,只需在每个目标(在这种情况下为.side-nav > [data-page]元素)上附加一个侦听器即可。

这样可以避免所有检测问题,例如点击了实际的div等,其中this将成为目标元素,例如this.dataset.page

...以及奖金;更少的代码,更少的错误,更容易维护。

注意,您使用的data.set.param应该是dataset.param,这里的parampagedata-page

堆栈片段

document.querySelectorAll('.side-nav > [data-page]').forEach(el => {
  el.addEventListener('click', function() {
    console.log(this.dataset.page);
  });
});
<div class="side-nav">
    <div class="side-nav-button side-nav-active pointer" id="dashboard-shortcut" title="Home" data-page="dashboard">
        <p class="side-nav-button-icon"><i class="fas fa-home">Home</i></p>
    </div>
    <div class="side-nav-button side-nav-active pointer" id="another-div-shortcut" title="page2" data-page="page2">
        <p class="side-nav-button-icon"><i class="fas fa-cross">Page2</i></p>
    </div>
</div>


根据评论,OP表示他们确实动态加载元素,并添加了第二个示例。

我们可以使用if (e.target !== this && this.contains(e.target))进行检查,以确保在继续之前它不是某个人单击的.side.nav本身(e.target !== this),而是它的一个子级(this.contains(e.target))。

如果使用e.target.closest('[data-page]').dataset.page,我们得到了目标元素。

请注意,如另一条评论中所述,如果您将.side-nav与具有相同类别/属性的子级嵌套在一起,则可能需要进行调整,例如将closest()的选择器扩展到closest('.side-nav > [data-page]')应该足够,仍然很难确定。

堆栈片段

document.querySelector('.side-nav').addEventListener('click', function(e) {
  if (e.target !== this && this.contains(e.target)) {    
    console.log(e.target.closest('[data-page]').dataset.page);  
  }
});
<div class="side-nav">
    <div class="side-nav-button side-nav-active pointer" id="dashboard-shortcut" title="Home" data-page="dashboard">
        <p class="side-nav-button-icon"><i class="fas fa-home">Home</i></p>
    </div>
    <div class="side-nav-button side-nav-active pointer" id="another-div-shortcut" title="page2" data-page="page2">
        <p class="side-nav-button-icon"><i class="fas fa-cross">Page2</i></p>
    </div>
</div>

答案 1 :(得分:0)

//使用最接近方法查找实际元素

document.querySelector('.side-nav').addEventListener('click', e => {
    var elem = e.target.closest("[data-page]");
    if (elem && elem.getAttribute('data-page') !== 'root') {
        console.log(elem.getAttribute("data-page"));
    }
});

注意:防止停止查找元素直到root

<div class="side-nav" data-page='root'>
    <div class="side-nav-button side-nav-active pointer" id="dashboard-shortcut" title="Home" data-page="dashboard">
        <p class="side-nav-button-icon"><i class="fas fa-home"></i></p>
    </div>
   <div class="side-nav-button side-nav-active pointer" id="another-div-shortcut" title="page2" data-page="page2">
        <p class="side-nav-button-icon"><i class="fas fa-cross"></i></p>
    </div>
</div>

答案 2 :(得分:0)

事件的target属性将是单击的元素。在您的方案中,单击的元素可以是示例中显示的任何HTML元素:p内的i.side-nav-button.side-nav-button本身甚至是{{ 1}}中附加事件的位置。

我能想到的是获取目标元素,检查是否具有.side-nav属性,如果没有,请寻找父项并重复检查。这样,例如,如果单击data-page元素,它将检查自身,然后将检查i并最终检查其p

因此:

.side-nav-button