Javascript 简明教程

JavaScript - Event Bubbling

Event Bubbling

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

Event Bubbling Steps

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

Event Triggering

  1. 事件在特定 DOM 元素上触发,例如单击按钮或按下键。

  2. 这是事件传播的起点。

Capturing Phase (optional)

  1. 事件可以选择通过捕获阶段。此阶段从 DOM 树的根部开始并朝向目标元素移动。

  2. 在此阶段,使用第三个参数 true 注册到 addEventListener 方法的事件处理程序将被执行。

Target Phase

  1. 该事件到达目标元素,也就是最初发生该事件的那个元素。

Bubbling Phase

  1. 在目标阶段之后,事件将从目标元素向 DOM 树的根部冒泡。

  2. 在此期间,未注册第三个参数或将第三个参数设置为 false 的事件处理程序将被执行。

Event Bubbling using 2 Nested DIVs

在嵌套 <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>

Event Bubbling using 3 Nested Levels

在这个包含三个嵌套级别的 <div> 元素示例中,事件冒泡以在最内部的 3 级 <div> 上的点击触发父级 2 和父级 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>