Javascript 简明教程

JavaScript - Event Bubbling

Event Bubbling

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

Event bubbling is a concept in JavaScript that refers to the order in which events are handled as they propagate through the DOM (Document Object Model) hierarchy. When an event occurs on a particular element, such as a click or a keypress, it can trigger handlers not only on that specific element but also on its ancestors in the DOM tree.

Event Bubbling Steps

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

Here’s a step-by-step explanation of event bubbling −

Event Triggering

  1. An event is triggered on a specific DOM element, like a button being clicked or a key being pressed.

  2. This is the starting point of the event propagation.

Capturing Phase (optional)

  1. The event can optionally go through the capturing phase. This phase starts from the root of the DOM tree and moves towards the target element.

  2. During this phase, event handlers registered with the addEventListener method using the third parameter true will be executed.

Target Phase

  1. The event reaches the target element, the one on which the event originally occurred.

Bubbling Phase

  1. After the target phase, the event starts to bubble up from the target element towards the root of the DOM tree.

  2. During this phase, event handlers registered without the third parameter or with the third parameter set to false will be executed.

Event Bubbling using 2 Nested DIVs

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

In this example of nested <div> elements, event bubbling is evident as the click event on the child <div> propagates up through the DOM hierarchy to trigger the click event listener on the parent <div>. Despite being clicked on the child, both the child and parent event listeners respond to the click event sequentially.

这种行为展示了 DOM 中的默认事件冒泡机制,其中事件从目标元素遍历到它的祖先元素,这样多个元素对同一事件做出响应。在控制台中,当点击子项 <div> 时,将在子项和父项事件侦听器的日志消息中显示,说明事件冒泡过程。

This behaviour showcases the default event bubbling mechanism in the DOM, where events traverse from the target element up to its ancestors, allowing multiple elements to respond to the same event. In the console, upon clicking the child <div>, the log messages for both the child and parent event listeners are displayed, illustrating the event bubbling process.

<!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> 元素上连续的点击事件侦听器的方式演示。使用独特背景颜色进行样式设置,每个级别在视觉上都表示其层次结构。

In this example with three nested levels of <div> elements, event bubbling is demonstrated as a click on the innermost Level 3 <div> triggers successive click event listeners on the parent Level 2 and Level 1 <div> elements. Styled with distinctive background colours, each level visually represents its hierarchy.

在点击 3 级 <div> 时,事件将向上传播,调用用于更高级别元素的事件侦听器。控制台日志显示了指示所单击级别及其背景颜色的消息,展示了精简的事件冒泡机制用于处理 DOM 中的嵌套结构。

Upon clicking the Level 3 <div>, the event propagates up, invoking event listeners for higher-level elements. Console logs reveal messages indicating the clicked level and its background colour, showcasing the streamlined event bubbling mechanism for handling nested structures in the 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>