当事件发生在 DOM 元素上时,该事件并不完全发生在那个元素上。在捕获阶段,事件从​​window​​开始,一直到触发事件的元素。

假设有如下的 HTML 结构:

<div class="grandparent">
<div class="parent">
<div class="child">1</div>
</div>
</div>

对应的 JS 代码:

function addEvent(el, event, callback, isCapture = false) {
if (!el || !event || !callback || typeof callback !== 'function') return;
if (typeof el === 'string') {
el = document.querySelector(el);
};
el.addEventListener(event, callback, isCapture);
}

addEvent(document, 'DOMContentLoaded', () => {
const child = document.querySelector('.child');
const parent = document.querySelector('.parent');
const grandparent = document.querySelector('.grandparent');

addEvent(child, 'click', function (e) {
console.log('child');
});

addEvent(parent, 'click', function (e) {
console.log('parent');
});

addEvent(grandparent, 'click', function (e) {
console.log('grandparent');
});

addEvent(document, 'click', function (e) {
console.log('document');
});

addEvent('html', 'click', function (e) {
console.log('html');
})

addEvent(window, 'click', function (e) {
console.log('window');
})

});

​addEventListener​​​方法具有第三个可选参数​​useCapture​​​,其默认值为​​false​​​,事件将在冒泡阶段中发生,如果为​​true​​​,则事件将在捕获阶段中发生。如果单击​​child​​​元素,它将分别在控制台上打印​​window​​​,​​document​​​,​​html​​​,​​grandparent​​​和​​parent​​,这就是事件捕获