推荐答案
浏览器的事件模型分为三个阶段:事件捕获阶段、目标阶段和事件冒泡阶段。事件捕获和事件冒泡是事件传播的两个不同阶段。
- 事件捕获:事件从最外层的祖先元素向下传播到目标元素。在这个过程中,事件会依次触发每个祖先元素上的捕获事件处理程序。
- 事件冒泡:事件从目标元素向上传播到最外层的祖先元素。在这个过程中,事件会依次触发每个祖先元素上的冒泡事件处理程序。
默认情况下,事件处理程序是在冒泡阶段触发的,但可以通过设置 addEventListener 的第三个参数为 true 来在捕获阶段触发事件处理程序。
本题详细解读
事件捕获阶段
事件捕获阶段是事件传播的第一个阶段。事件从 window 对象开始,沿着 DOM 树向下传播,直到到达目标元素。在这个过程中,事件会依次触发每个祖先元素上的捕获事件处理程序。
例如,假设有以下 HTML 结构:
<div id="outer">
<div id="inner">
<button id="target">Click me</button>
</div>
</div>如果在 outer 和 inner 元素上都注册了捕获事件处理程序,那么在点击 target 按钮时,事件会首先触发 outer 的捕获事件处理程序,然后触发 inner 的捕获事件处理程序,最后到达 target 元素。
目标阶段
目标阶段是事件传播的第二个阶段。在这个阶段,事件到达目标元素,并触发目标元素上的事件处理程序。
事件冒泡阶段
事件冒泡阶段是事件传播的最后一个阶段。事件从目标元素开始,沿着 DOM 树向上传播,直到到达 window 对象。在这个过程中,事件会依次触发每个祖先元素上的冒泡事件处理程序。
继续上面的例子,如果在 outer 和 inner 元素上都注册了冒泡事件处理程序,那么在点击 target 按钮时,事件会首先触发 target 元素上的事件处理程序,然后触发 inner 的冒泡事件处理程序,最后触发 outer 的冒泡事件处理程序。
事件捕获与事件冒泡的区别
- 传播方向:事件捕获是从外向内传播,而事件冒泡是从内向外传播。
- 触发顺序:事件捕获阶段先于事件冒泡阶段触发。
- 默认行为:默认情况下,事件处理程序是在冒泡阶段触发的,但可以通过设置
addEventListener的第三个参数为true来在捕获阶段触发事件处理程序。
示例代码
// www.javascriptcn.com code example
document.getElementById('outer').addEventListener('click', function() {
console.log('Outer element captured');
}, true);
document.getElementById('inner').addEventListener('click', function() {
console.log('Inner element captured');
}, true);
document.getElementById('target').addEventListener('click', function() {
console.log('Target element clicked');
});
document.getElementById('inner').addEventListener('click', function() {
console.log('Inner element bubbled');
});
document.getElementById('outer').addEventListener('click', function() {
console.log('Outer element bubbled');
});在这个例子中,点击 target 按钮时,控制台输出的顺序将是:
Outer element captured Inner element captured Target element clicked Inner element bubbled Outer element bubbled