
事件冒泡
冒泡意味著事件從目標(biāo)元素(即button用戶點擊)向上傳播到其祖先樹,從最近的元素開始。默認情況下,所有事件都會冒泡。
為了更好地理解事件冒泡,請考慮以下 HTML 示例,我們將在本文的大部分內(nèi)容中引用該示例:
HTML
<html> ?<body> ? ?<div id="btn-container"> ? ? ?<button class="btn">Click me</button> ? ?</div> ?</body> </html>
JavaScript
const ancestors = [
? window, document, document.documentElement,
? document.body, document.getElementById('btn-container')
];
// 目標(biāo)階段
document.querySelector('.btn').addEventListener('click', e => {
? console.log(`Hello from ${e.target}`);
});
// 泡沫階段
ancestors.forEach(a => {
? a.addEventListener('click', e => {
? ? console.log(`Hello from ${e.currentTarget}`);
? });
});
如果我們?yōu)闃渲械拿總€元素添加一個事件偵聽器,如上所示,我們會看到第一個觸發(fā)了一個偵聽器button,然后其他每個元素都從最近的祖先一直觸發(fā)到Window.
事件捕獲
捕獲與冒泡完全相反,這意味著外部事件處理程序在最具體的處理程序(即 上的處理程序button)之前被觸發(fā)。請注意,首先運行所有捕獲事件處理程序,然后運行所有冒泡事件處理程序。
您可以通過將第三個參數(shù)應(yīng)用于 EventTarget.addEventListener,將其設(shè)置為 true 來使用事件捕獲。例如:
// 捕獲階段
ancestors.forEach(a => {
? a.addEventListener('click', e => {
? ? console.log(`Hello from ${e.currentTarget}`);
? }, true);
});
給定這段代碼,我們會看到第一個 button的每個祖先觸發(fā)了一個偵聽器,然后觸發(fā)了 button 偵聽器。
事件傳播
解釋了事件冒泡和捕獲之后,我們現(xiàn)在可以解釋事件傳播的三個階段:
捕獲階段,事件從根元素Document開始并向下移動到目標(biāo)元素的祖先Window。
目標(biāo)階段,事件在事件目標(biāo)(例如button用戶點擊)上被觸發(fā)。
冒泡階段,事件通過目標(biāo)元素的祖先冒泡,直到根元素Document,最后為Window。
事件委托
事件委托是指委托事件偵聽父元素而不是直接將事件偵聽器添加到事件目標(biāo)的想法。使用這種技術(shù),父級可以根據(jù)需要捕獲和處理冒泡事件。
window.addEventListener('click', e => {
? if (e.target.className === 'btn') console.log('Hello there!');
});
在上面的示例中,我們將事件處理委托給button 到 Window并用Event.target獲取原始事件的目標(biāo)。
使用事件委托模式有兩個優(yōu)勢:
通過使用事件委托,我們可以在大量元素上偵聽事件,而無需單獨附加事件偵聽器,這可以提供性能優(yōu)勢。
通過使用事件委托,動態(tài)元素(即隨著時間的推移從 DOM中添加或刪除)可以捕獲和處理它們的事件,而無需注冊或刪除偵聽器。
更多內(nèi)容請訪問我的網(wǎng)站:https://www.icoderoad.com