事件冒泡
冒泡意味着事件从目标元素(即button用户点击)向上传播到其祖先树,从最近的元素开始。默认情况下,所有事件都会冒泡。
为了更好地理解事件冒泡,请考虑以下 HTML 示例,我们将在本文的大部分内容中引用该示例:
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')
];
// 目标阶段
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}`);
});
});
如果我们为树中的每个元素添加一个事件侦听器,如上所示,我们会?看到第一个触发了一个侦听器button,然后其他每个元素都从最近的祖先一直触发到Window.
事件捕获
捕获与冒泡完全相反,这意味着外部事件处理程序在最具体的处理程序(即 上的处理程序button)之前被触发。请注意,首先运行所有捕获事件处理程序,然后运行所有冒泡事件处理程序。
您可以通过将第三个参数应用于 EventTarget.addEventListener,将其设置为 true 来使用事件捕获。例如:
// 捕获阶段
ancestors.forEach(a => {
a.addEventListener('click', e => {
console.log(`Hello from ${e.currentTarget}`);
}, true);
});
给定这段代码,我们会看到第一个 button 的每个祖先触发了一个侦听器,然后触发了 button 侦听器。
事件传播
解释了事件冒泡和捕获之后,我们现在可以解释事件传播的三个阶段:
- 捕获阶段,事件从根元素Document开始并向下移动到目标元素的祖先Window。
- 目标阶段,事件在事件目标(例如button用户点击)上被触发。
- 冒泡阶段,事件通过目标元素的祖先冒泡,直到根元素Document,最后为Window。
事件委托
事件委托是指委托事件侦听父元素而不是直接将事件侦听器添加到事件目标的想法。使用这种技术,父级可以根据需要捕获和处理冒泡事件。
window.addEventListener('click', e => {
if (e.target.className === 'btn') console.log('Hello there!');
});
在上面的示例中,我们将事件处理委托给button 到 Window并用Event.target获取原始事件的目标。
使用事件委托模式有两个优势:
- 通过使用事件委托,我们可以在大量元素上侦听事件,而无需单独附加事件侦听器,这可以提供性能优势。
- 通过使用事件委托,动态元素(即随着时间的推移从 DOM 中添加或删除)可以捕获和处理它们的事件,而无需注册或删除侦听器。
更多内容请访问我的网站:https://www.icoderoad.com