事件捕获和事件冒泡与事件流有关系。
以下代码展示了实例:
addEventListener 的第三个参数(useCapture
)的 true
和 false
决定了事件处理函数是在 捕获阶段 还是 冒泡阶段 执行:
false
(默认值)是冒泡阶段
true 代表捕获阶段
<!DOCTYPE html>
<html>
<head>
<title>事件捕获与冒泡示例</title>
<style>
#grandparent {
padding: 20px;
background-color: #f0f0f0;
}
#parent {
padding: 20px;
background-color: #d0d0d0;
}
#child {
padding: 20px;
background-color: #b0b0b0;
}
button {
padding: 10px 20px;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
}
</style>
</head>
<body>
<div id="grandparent">
<div id="parent">
<div id="child">
<button id="btn">点击我</button>
</div>
</div>
</div>
<script>
// 1. 事件捕获阶段(从外到内)
document.getElementById('grandparent').addEventListener('click', function(e) {
console.log('Grandparent 捕获阶段触发');
}, true);
document.getElementById('parent').addEventListener('click', function(e) {
console.log('Parent 捕获阶段触发');
}, true);
document.getElementById('child').addEventListener('click', function(e) {
console.log('Child 捕获阶段触发');
}, true);
// 2. 事件冒泡阶段(从内到外)
document.getElementById('grandparent').addEventListener('click', function(e) {
console.log('Grandparent 冒泡阶段触发');
}, false);
document.getElementById('parent').addEventListener('click', function(e) {
console.log('Parent 冒泡阶段触发');
}, false);
document.getElementById('child').addEventListener('click', function(e) {
console.log('Child 冒泡阶段触发');
}, false);
// 3. 目标阶段(按钮点击)
document.getElementById('btn').addEventListener('click', function(e) {
console.log('按钮目标阶段触发');
});
</script>
</body>
</html>
事件捕获是从外层到内层传递事件流,事件冒泡是从内层向外层传递事件流
阻止事件冒泡:
<div id="parent">
<button id="child">点击我</button>
</div>
<script>
document.getElementById('parent').addEventListener('click', () => {
console.log('父元素冒泡触发');
});
document.getElementById('child').addEventListener('click', (e) => {
e.stopPropagation(); // 阻止冒泡
console.log('子元素冒泡触发,但已阻止向上传播');
});
</script>
控制台打印:
阻止事件捕获:
<div id="grandparent">
<div id="parent">
<button id="child">点击我</button>
</div>
</div>
<script>
document.getElementById('grandparent').addEventListener('click', (e) => {
e.stopImmediatePropagation(); // 阻止捕获阶段传播
console.log('祖父元素捕获触发,但已阻止后续传播');
}, true); // 捕获阶段监听
document.getElementById('parent').addEventListener('click', () => {
console.log('父元素捕获触发'); // 不会执行
}, true);
</script>
控制台打印: