Javascript的事件模型在触发时可以分为3个阶段:捕获、目标、冒泡。
事件先捕获,再冒泡,比如下面这个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
window.addEventListener('load',()=>
{
let Level_1=document.getElementById('Level_1');
let Level_2=document.getElementById('Level_2');
let Level_3=document.getElementById('Level_3');
let Level_4=document.getElementById('Level_4');
Level_1.addEventListener('click',function(){console.log('Bubbling: ',this.id)},false);
Level_2.addEventListener('click',function(){console.log('Bubbling: ',this.id)},false);
Level_3.addEventListener('click',function(){console.log('Bubbling: ',this.id)},false);
Level_4.addEventListener('click',function(){console.log('Bubbling: ',this.id)},false);
Level_1.addEventListener('click',function(){console.log('Capture: ',this.id)},true);
Level_2.addEventListener('click',function(){console.log('Capture: ',this.id)},true);
Level_3.addEventListener('click',function(){console.log('Capture: ',this.id)},true);
Level_4.addEventListener('click',function(){console.log('Capture: ',this.id)},true);
});
</script>
</head>
<body>
<div id='Level_1'>
<div id='Level_2'>
<div id='Level_3'>
<div id='Level_4' style='width:100px;height:100px;background-color:black;'></div>
</div>
</div>
</div>
</body>
</html>
这里有4个连续嵌套的div,每个div分别添加了捕获和冒泡(由addEventListener函数的第3个参数决定)的2个点击事件处理函数。
点击div之后在控制台输出:
Capture: Level_1
Capture: Level_2
Capture: Level_3
Bubbling: Level_4
Capture: Level_4
Bubbling: Level_3
Bubbling: Level_2
Bubbling: Level_1
事件从顶层div开始触发,直到目标div,之后再冒泡。但是对于目标div(即Level_4),捕获和冒泡的回调函数的执行顺序取决于addEventListener的调用顺序,即这两个回调函数的添加顺序,先添加则先调用。