JavaScript - 事件冒泡



事件冒泡

事件冒泡是 JavaScript 中的一个概念,指的是事件在 DOM(文档对象模型)层次结构中传播时处理的顺序。当事件发生在特定元素上时,例如单击或按键,它不仅可以触发该特定元素上的处理程序,还可以触发 DOM 树中其祖先上的处理程序。

事件冒泡步骤

以下是事件冒泡的分步说明 -

事件触发

  • 在特定的 DOM 元素上触发事件,例如单击按钮或按下键。
  • 这是事件传播的起点。

捕获阶段(可选)

  • 事件可以选择进入捕获阶段。此阶段从 DOM 树的根开始,向目标元素移动。
  • 在此阶段,将执行使用第三个参数 true 向 addEventListener 方法注册的事件处理程序。

目标阶段

  • 事件到达 target 元素,即最初发生事件的元素。

冒泡阶段

  • 在目标阶段之后,事件开始从目标元素向 DOM 树的根部冒泡。
  • 在此阶段,将执行未注册第三个参数或第三个参数设置为 false 的事件处理程序。

使用 2 个嵌套 DIV 的事件冒泡

在这个嵌套的 <div> 元素示例中,当子 <div> 上的 click 事件通过 DOM 层次结构向上传播以触发父 <div> 上的 click 事件侦听器时,事件冒泡是显而易见的。尽管在子事件上被单击,但子事件侦听器和父事件侦听器都会按顺序响应 click 事件。

此行为展示了 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。

使用 3 个嵌套关卡的事件冒泡

在此示例中,具有三个嵌套级别的 <div> 元素,事件冒泡演示为单击最内层的 Level 3 <div> 会触发父级 Level 2 和 Level 1 <div> 元素上的连续单击事件侦听器。每个级别都使用独特的背景颜色设置样式,直观地表示其层次结构。

单击级别 3 <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>