![](/img/trans.png)
[英]How to override a parent event listener when a child element is clicked in Javascript?
[英]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 時獲取data-page
屬性,即單擊 div dashboard-shortcut
時。 有什么辦法可以做到這一點嗎?
非常感謝您提前。
除非您希望動態添加元素,否則不要使用事件委托,只需在每個目標上附加一個偵聽器,在本例中為.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
),而是它的一個孩子( 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>
// 使用最接近的方法來查找實際元素
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 元素: .side-nav-button
內的p
或i
, .side-nav-button
本身,甚至是您附加的.side-nav
事件。
我能想到的是獲取目標元素,檢查是否有data-page
屬性,如果沒有,則為父元素 go 並重復檢查。 這樣,例如,如果單擊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);
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.