JavaScript - 事件冒泡
事件冒泡
事件冒泡是 JavaScript 中的一个概念,指的是事件在 DOM(文档对象模型)层次结构中传播时的处理顺序。当特定元素上发生事件(例如点击或按下键盘)时,它不仅会触发该特定元素的处理程序,还会触发其在 DOM 树中的祖先元素的处理程序。
事件冒泡步骤
以下是事件冒泡的分步说明 -
事件触发
事件在特定 DOM 元素上触发,例如点击按钮或按下按键。
这是事件传播的起点。
捕获阶段(可选)
事件可以选择经历捕获阶段。此阶段从 DOM 树的根开始,向目标元素移动。
在此阶段,将执行使用 addEventListener 方法注册且第三个参数为 true 的事件处理程序。
目标阶段
事件到达目标元素,即事件最初发生的元素。
冒泡阶段
目标阶段结束后,事件开始从目标元素向上冒泡,向 DOM 树的根元素移动。
在此阶段,将执行未使用第三个参数或将第三个参数设置为 false 的事件处理程序。
使用两个嵌套 DIV 进行事件冒泡
在此嵌套 DIV 的示例中对于 <div> 元素,事件冒泡现象显而易见,因为子元素 <div> 上的点击事件会沿着 DOM 层次结构向上传播,从而触发父元素 <div> 上的点击事件监听器。尽管点击的是子元素,但子元素和父元素的事件监听器都会按顺序响应点击事件。
此行为展示了 DOM 中的默认事件冒泡机制,事件从目标元素向上遍历到其祖先元素,从而允许多个元素响应同一事件。在控制台中,点击子元素 <div> 时,会显示子元素和父元素事件监听器的日志消息,以说明事件冒泡的过程。
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.parent {
width: 600px;
height: 200px;
background-color: #eee;
position: relative;
cursor: pointer;
}
.child {
width: 400px;
height: 100px;
background-color: #66c2ff;
position: absolute;
top: 50px;
left: 50px;
}
#message {
margin-top: 10px;
font-weight: bold;
}
</style>
</head>
<body>
<h2>Nested Divs</h2>
<div class="parent" id="parentDiv">
<div class="child" id="childDiv">Click me!</div>
</div>
<div id="message"></div>
<script>
let messageElement = document.getElementById('message');
document.getElementById('parentDiv').addEventListener('click', function () {
messageElement.innerHTML+='Parent div clicked<br>';
});
document.getElementById('childDiv').addEventListener('click', function () {
messageElement.innerHTML+='Child div clicked<br>';
});
</script>
</body>
</html>
灰色框表示父 div,蓝色框表示子 div。
使用三层嵌套的事件冒泡
本例中,<div> 元素嵌套了三层,事件冒泡的演示如下:点击最内层三层 <div> 元素会触发父级二层和一层 <div> 元素上的连续点击事件监听器。每一层都采用独特的背景色,直观地展现了其层级结构。
点击三层 <div> 元素时,事件会向上传播,调用更高层级元素的事件监听器。控制台日志会显示点击层级及其背景色的消息,展现了用于处理 DOM 中嵌套结构的精简事件冒泡机制。
<!DOCTYPE html>
<html>
<head>
<style>
.level1 {
background-color: #ff9999;
padding: 20px;
text-align: center;
max-width: 80%;
cursor: pointer;
}
.level2 {
background-color: #99ff99;
padding: 15px;
}
.level3 {
background-color: #9999ff;
padding: 10px;
cursor: pointer;
}
#message {
margin-top: 10px;
font-weight: lighter;
border: 1px solid #ddd;
padding: 10px;
max-width: 80%;
background-color: #f9f9f9;
border-radius: 5px;
font-family: 'Arial', sans-serif;
font-size: 14px;
color: #333;
}
</style>
</head>
<body>
<div class="level1" id="div1">
Level 1
<div class="level2" id="div2">
Level 2
<div class="level3" id="div3">
Level 3 (Click me!)
</div>
</div>
</div>
<div id="message"></div>
<script>
const messageElement = document.getElementById("message");
document.getElementById('div1').addEventListener("click", function (event) {
messageElement.innerHTML += "Clicked on Level 1, Background Color:" + getComputedStyle(event.target).backgroundColor + "<br>";
});
document.getElementById('div2').addEventListener("click", function (event) {
messageElement.innerHTML += "Clicked on Level 2, Background Color:" + getComputedStyle(event.target).backgroundColor + "<br>";
});
document.getElementById('div3').addEventListener('click', function (event) {
messageElement.innerHTML +="Clicked on Level 3, Background Color:" + getComputedStyle(event.target).backgroundColor + "<br>";
});
</script>
</body>
</html>

