面试题答案
一键面试事件冒泡与捕获流程
- 事件捕获:当一个事件发生在DOM元素上时,首先从最外层的祖先元素开始,依次向内层元素传递,直到到达目标元素。这个过程就像水从外向内渗透,依次“捕获”事件。例如,有一个页面结构为
document -> html -> body -> div -> p
,如果点击p
元素,事件会从document
开始,依次经过html
、body
、div
,最后到达p
。 - 事件冒泡:事件到达目标元素后,会从目标元素开始,依次向外层的祖先元素传递。就像气泡从水底向上冒一样。还是以上面的页面结构为例,点击
p
元素,事件会从p
开始,依次经过div
、body
、html
,最后到达document
。
冒泡阶段添加事件监听器
在JavaScript中,可以使用 addEventListener
方法的第三个参数来控制事件监听器在冒泡阶段还是捕获阶段触发。默认情况下,第三个参数为 false
,表示在冒泡阶段触发。例如:
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="inner">点击我</div>
</div>
<script>
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
inner.addEventListener('click', function () {
console.log('inner div 冒泡阶段触发');
});
outer.addEventListener('click', function () {
console.log('outer div 冒泡阶段触发');
});
</script>
</body>
</html>
当点击 inner
div 时,首先会执行 inner
div 的点击事件,然后由于事件冒泡,会执行 outer
div 的点击事件。
捕获阶段添加事件监听器
将 addEventListener
方法的第三个参数设置为 true
,即可在捕获阶段触发事件监听器。例如:
<!DOCTYPE html>
<html>
<body>
<div id="outer">
<div id="inner">点击我</div>
</div>
<script>
const outer = document.getElementById('outer');
const inner = document.getElementById('inner');
inner.addEventListener('click', function () {
console.log('inner div 捕获阶段触发');
}, true);
outer.addEventListener('click', function () {
console.log('outer div 捕获阶段触发');
}, true);
</script>
</body>
</html>
当点击 inner
div 时,首先会执行 outer
div 的点击事件(因为是在捕获阶段,从外向内传递),然后执行 inner
div 的点击事件。