要同时在捕获阶段和冒泡阶段添加事件监听器
方法一:分别使用 addEventListener
绑定
对于同一个元素的同一个事件类型,可以分别调用两次 addEventListener
方法,一次将第三个参数设置为 true
以在捕获阶段添加监听器,另一次将第三个参数设置为 false
或省略该参数以在冒泡阶段添加监听器。以下是一个示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>同时添加捕获和冒泡阶段的事件监听器</title>
<style>
#outer {
width: 200px;
height: 200px;
background-color: lightgray;
}
#inner {
width: 100px;
height: 100px;
background-color: gray;
}
</style>
</head>
<body>
<div id="outer">
Outer
<div id="inner">Inner</div>
</div>
<script>
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
// 在捕获阶段为 outer 元素添加 click 事件监听器
outer.addEventListener('click', function () {
console.log('outer capture');
}, true);
// 在冒泡阶段为 outer 元素添加 click 事件监听器
outer.addEventListener('click', function () {
console.log('outer bubble');
});
// 在捕获阶段为 inner 元素添加 click 事件监听器
inner.addEventListener('click', function () {
console.log('inner capture');
}, true);
// 在冒泡阶段为 inner 元素添加 click 事件监听器
inner.addEventListener('click', function () {
console.log('inner target and bubble');
});
// 当点击 inner 元素时,控制台输出顺序为:outer capture、inner capture、inner target and bubble、outer bubble
</script>
</body>
</html>
在上述示例中,分别为 outer
元素和 inner
元素在捕获阶段和冒泡阶段添加了 click
事件监听器。当点击 inner
元素时,可以看到按照捕获阶段先外后内,然后是目标阶段,最后是冒泡阶段从内到外的顺序执行了相应的事件处理函数。
方法二:使用事件委托并结合判断事件阶段
另一种方式是利用事件委托,将事件监听器绑定在共同的祖先元素上,并在事件处理函数中通过检查事件对象的 eventPhase
属性来判断事件处于捕获阶段还是冒泡阶段,从而执行不同的逻辑。以下是一个示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用事件委托同时处理捕获和冒泡阶段的事件</title>
<style>
#container {
width: 300px;
height: 300px;
background-color: lightgray;
}
#child {
width: 150px;
height: 150px;
background-color: gray;
}
</style>
</head>
<body>
<div id="container">
Container
<div id="child">Child</div>
</div>
<script>
const container = document.getElementById('container');
container.addEventListener('click', function (event) {
if (event.eventPhase === 1) {
console.log('捕获阶段 - 祖先元素:container');
} else if (event.eventPhase === 2) {
console.log('目标阶段 - 目标元素:', event.target.id);
} else if (event.eventPhase === 3) {
console.log('冒泡阶段 - 祖先元素:container');
}
}, true);
// 当点击 child 元素时,控制台会输出捕获阶段的 container、目标阶段的 child、冒泡阶段的 container
</script>
</body>
</html>
在这个示例中,将 click
事件监听器绑定在 container
元素上,并在事件处理函数中根据 eventPhase
属性的值来判断事件所处的阶段,从而实现了在一个事件处理函数中同时处理捕获阶段和冒泡阶段的逻辑。
通过以上两种方法,可以根据具体的需求和场景,灵活地同时在捕获阶段和冒泡阶段添加事件监听器,以实现更复杂的事件处理和交互逻辑。