DOM事件流包括三个阶段。
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
1. 事件捕获阶段
事件对象会随着DOM事件流从Window依次向下,最终传递给事件目标。但是在这个过程开始之前,事件对象的传递路径需要先被确定下来。
当事件发生时,首先发生的是事件捕获,为父元素截获事件提供了机会。
(addEventListener最后一个参数,为true则代表使用事件捕获模式,false则表示使用事件冒泡模式。)
window.addEventListener('click', function() {
console.log('4. You click window');
}, true);
2.处于目标与事件冒泡阶段
事件到了具体元素时,在具体元素上发生,并且被看成冒泡阶段的一部分。
随后,冒泡阶段发生,事件开始冒泡。
3.事件冒泡阶段
事件冒泡即事件开始时,由最具体的目标元素接收(也就是事件发生所在的节点),然后逐级传播到较为不具体的节点。
事件冒泡过程,是可以被阻止的 e.stopPropagation()
。
button.addEventListener('click', function(event) {
// event为事件对象
console.log('1. You click Button');
event.stopPropagation();
console.log('Stop Propagation!');
}, false);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style>
div{
positon: absolute;
top: 0;
left: 0;
}
.outer{
width: 400px;
height: 400px;
background-color: red;
}
.center{
width: 300px;
height: 300px;
background-color: purple;
}
.inner{
width: 200px;
height: 200px;
background-color: green;
}
</style>
<body>
<div class="outer">
<div class="center">
<div class="inner"></div>
</div>
</div>
<script>
var oOuter = document.getElementsByClassName('outer')[0];
var oCenter = document.getElementsByClassName('center')[0];
var oInner = document.getElementsByClassName('inner')[0];
oOuter.addEventListener('click', function(){
console.log('捕获outer');
}, true);
oCenter.addEventListener('click', function(){
console.log('捕获center');
}, true);
oInner.addEventListener('click', function(){
console.log('捕获inner');
}, true);
oOuter.addEventListener('click', function(){
console.log('冒泡outer');
}, false);
oCenter.addEventListener('click', function(){
console.log('冒泡center');
}, false);
oInner.addEventListener('click', function(){
console.log('冒泡inner');
}, false);
</script>
</body>
</html>
当点击了outer时,依次打印:捕获outer,冒泡outer。
当点击了center时,依次打印:捕获outer,捕获center,冒泡center,冒泡outer。
当点击了inner时,依次打印:捕获outer,捕获center,捕获inner,冒泡inner,冒泡center,冒泡outer。
但是把最后的冒泡inner事件写到捕获inner事件之前,依次打印:捕获outer,捕获center,冒泡inner,捕获inner,冒泡center,冒泡outer。
由此可以得出来结论,点击了目标节点后,捕获阶段里事件会从外向目标传递;到了目标阶段,捕获和冒泡的执行顺序按照事件被定义的先后顺序执行;最后冒泡阶段,又会由目标向外进行传递。