JavaScript - 事件捕获
事件捕获
JavaScript 中的事件捕获是事件传播模型的初始阶段,事件从文档树的根向下传播到目标元素。在此阶段,浏览器会在到达目标元素本身之前,先在目标元素的祖先元素上捕获事件。
事件捕获和事件冒泡是 JavaScript 事件传播模型中的两个阶段。在事件捕获中,浏览器从文档层次结构的根开始捕获并触发事件,然后向下移动到目标元素。另一方面,事件冒泡发生在事件到达目标元素之后,然后从目标元素向上冒泡到根元素。
捕获对于处理更高级别祖先元素的事件非常有用,而冒泡是默认行为,事件会从目标元素沿层次结构向上传播。理解这两个阶段对于有效地处理事件和操纵事件流至关重要。
让我们看看事件捕获的一些重要方面。
| 方面 | 描述 |
|---|---|
| 阶段 | 事件捕获是事件传播模型的初始阶段。 |
| 方向 | 捕获按元素层次结构的反向顺序进行,从文档树的根向下到目标元素。 |
| 用例 | 当您希望在事件到达目标元素或触发任何冒泡阶段之前在更高级别的祖先元素处拦截和处理事件时非常有用处理程序。 |
| 注册 | 使用 addEventListener 的第三个参数为捕获阶段注册事件监听器(例如,element.addEventListener('click', myFunction, true);)。 |
| 传播 | 在目标阶段和冒泡阶段之前自动传播。事件沿层级结构向下流动,触发每个祖先元素的捕获阶段处理程序。 |
| 防止默认行为 | 在捕获阶段使用 event.preventDefault() 可防止事件在到达目标之前发生默认行为。 |
| 停止传播 | 在捕获阶段使用 event.stopPropagation() 可停止事件的进一步传播,防止其到达目标元素或触发冒泡阶段处理程序。 |
示例:基本事件捕获
在此示例中,我们有一个容器 div(container)和一个按钮(myButton)。使用 addEventListener 并传入 true 参数添加两个捕获阶段事件监听器以启用捕获。点击按钮时,两个捕获阶段的日志消息(容器点击和按钮点击)都会显示。这展示了事件从文档根目录向下传递到目标元素的捕获阶段。
<!DOCTYPE html>
<html>
<body>
<div id="container">
<button id="myButton">Click me!</button>
</div>
<div id = "output"></div>
<script>
const output = document.getElementById('output');
document.getElementById('container').addEventListener('click', function(event) {
output.innerHTML += 'Capturing phase - Container clicked' + "<br>";
}, true);
document.getElementById('myButton').addEventListener('click', function(event) {
output.innerHTML += 'Capturing phase - Button clicked' + "<br>";
}, true);
</script>
</body>
</html>
示例:阻止默认行为
在此示例中,我们有一个超链接 (<a>),其 ID 为"link"。捕获阶段的事件监听器在捕获阶段附加到该链接。点击该链接时,将显示捕获阶段的日志消息(链接被点击),并使用 event.preventDefault() 阻止默认行为(导航到新页面)。
如果没有使用 event.preventDefault(),它会将页面导航到 https://www.cainiaomax.com。
<!DOCTYPE html>
<html>
<body>
<a href="https://www.cainiaomax.com" id="link">Click me to prevent default</a>
<script>
document.getElementById('link').addEventListener('click', function(event) {
alert('Capturing phase - Link clicked');
event.preventDefault(); // 防止默认行为(例如,导航到新页面)
}, true);
</script>
</body>
</html>
示例:捕获和停止传播
在此示例中,父级 div 的捕获阶段事件监听器通过使用"event.stopPropagation()"主动停止传播。只有点击按钮时,您才会看到捕获阶段的日志消息("父级被点击");但是,它不会在子元素的捕获阶段触发任何进一步的操作。这确实展示了一种在特定情况下阻止额外传播的有效方法。
<!DOCTYPE html>
<html>
<body>
<div id="parent">
<button id="child">Click me!</button>
</div>
<div id = "output"></div>
<script>
const output = document.getElementById('output');
document.getElementById('parent').addEventListener('click', function(event) {
output.innerHTML += 'Capturing phase - Parent clicked' + "<br>";
// 停止进一步传播到子元素
event.stopPropagation();
}, true);
document.getElementById('child').addEventListener('click', function(event) {
output.innerHTML += 'Capturing phase - Child clicked' + "<br>";
}, true);
</script>
</body>
</html>

