单击父项的子项时的事件侦听器
Event listener for when child of parent is clicked
我目前遇到一个问题,我希望能够检查点击事件的时间。我想为此使用事件委托,所以我在父 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 dashboard-shortcut
时,能够得到data-page
属性。有什么办法可以做到这一点吗?
非常感谢您。
// 使用最近 方法查找实际元素
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"));
}
});
注意:防止停止查找元素直到根
<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>
事件的target
属性 将是被点击的元素。在您的场景中,单击的元素可以是您在示例中显示的任何 HTML 元素:p
或 .side-nav-button
内的 i
、.side-nav-button
本身或甚至 .side-nav
您附加事件的地方。
我能想到的是获取目标元素,检查是否具有 data-page
属性,如果没有,则查找父元素并重复检查。这样,如果单击 i
元素,它将检查自身,然后检查 p
,最后检查其 .side-nav-button
.
因此:
document.querySelector('.side-nav').addEventListener('click', e => {
let el = e.target;
// The loop will stop when there's a page dataset
// Also will stop when the element that is checking is .side-nav (event.currentTarget), as there's no need to check beyond that.
while(el && el != event.currentTarget && !el.dataset.hasOwnProperty("page")) {
el = el.parentNode;
}
let page = el && el.dataset.page;
if (page) {
console.log(page);
}
});
除非您希望动态添加元素,否则不要使用事件委托,只需在每个目标上附加一个侦听器,在本例中为 .side-nav > [data-page]
个元素。
这样你就避免了所有的检测问题,比如点击了哪个实际的 div
等,其中 this
将是目标元素,例如this.dataset.page
.
...还有奖金;更少的代码,更不容易出错,更容易维护。
注意,你用的data.set.param
,应该是dataset.param
,这里的param
是page
(data-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
),而是其中一个 children (this.contains(e.target)
), 在继续之前。
并且如果使用 e.target.closest('[data-page]').dataset.page
我们得到了目标元素。
请注意,如另一条评论所述,如果您嵌套了 .side-nav
和具有相同 classes/attribute 的 children,您可能需要进行调整,例如将 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>
我目前遇到一个问题,我希望能够检查点击事件的时间。我想为此使用事件委托,所以我在父 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 dashboard-shortcut
时,能够得到data-page
属性。有什么办法可以做到这一点吗?
非常感谢您。
// 使用最近 方法查找实际元素
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"));
}
});
注意:防止停止查找元素直到根
<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>
事件的target
属性 将是被点击的元素。在您的场景中,单击的元素可以是您在示例中显示的任何 HTML 元素:p
或 .side-nav-button
内的 i
、.side-nav-button
本身或甚至 .side-nav
您附加事件的地方。
我能想到的是获取目标元素,检查是否具有 data-page
属性,如果没有,则查找父元素并重复检查。这样,如果单击 i
元素,它将检查自身,然后检查 p
,最后检查其 .side-nav-button
.
因此:
document.querySelector('.side-nav').addEventListener('click', e => {
let el = e.target;
// The loop will stop when there's a page dataset
// Also will stop when the element that is checking is .side-nav (event.currentTarget), as there's no need to check beyond that.
while(el && el != event.currentTarget && !el.dataset.hasOwnProperty("page")) {
el = el.parentNode;
}
let page = el && el.dataset.page;
if (page) {
console.log(page);
}
});
除非您希望动态添加元素,否则不要使用事件委托,只需在每个目标上附加一个侦听器,在本例中为 .side-nav > [data-page]
个元素。
这样你就避免了所有的检测问题,比如点击了哪个实际的 div
等,其中 this
将是目标元素,例如this.dataset.page
.
...还有奖金;更少的代码,更不容易出错,更容易维护。
注意,你用的data.set.param
,应该是dataset.param
,这里的param
是page
(data-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
),而是其中一个 children (this.contains(e.target)
), 在继续之前。
并且如果使用 e.target.closest('[data-page]').dataset.page
我们得到了目标元素。
请注意,如另一条评论所述,如果您嵌套了 .side-nav
和具有相同 classes/attribute 的 children,您可能需要进行调整,例如将 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>