事件冒泡和事件捕获
DOM 事件流会依次经历3个阶段(事件也会依次触发):
(1)捕获阶段:事件从文档的根节点流向目标对象。
(2)当前目标阶段:在目标对象上被触发。
(3)冒泡阶段:从目标对象回溯到文档的根节点。
默认事件是冒泡阶段发生,如果设置了事件,那么会依次触发,内层事件执行完成,才会冒泡触发上一层。
1、事件冒泡
如图是3个div,蓝色最内层,绿色中间层,青色最外层,鼠标点击蓝色区域
结果如下:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<style>
.div1 {
width: 600px;
height: 600px;
background-color: #00e9ea;
}
.div2{
width: 400px;
height: 400px;
background-color: #00cc00;
}
.div3{
width: 200px;
height: 200px;
background-color: #2d8cf0;
}
</style>
<body>
<div class='div1' onclick="handle1()">
<div class='div2' onclick="handle2()">
<div class='div3' onclick="handle3()"></div>
</div>
</div>
</body>
</html>
<script>
function handle1(){
console.log('我是最外层')
}
function handle2(){
console.log('我是中间层')
}
function handle3(){
console.log('我是最里层')
}
</script>
解释:点击一个位置(这个位置既属于最外层,又属于中间层,还属于最内层),那么事件发生顺序为:内层—>中间----->外层
2、事件捕获
示例1:将最外层div1绑定为捕获事件,那么触发顺序为:外层—>内层---->中间
代码:
<div class='div1'>
<div class='div2' onclick="handle2()">
<div class='div3' onclick="handle3()"></div>
</div>
</div>
<script>
function handle1(){
document.getElementsByClassName('div1')[0].addEventListener('click',()=>{
console.log('我是最外层')
},true)
}
handle1()
function handle2(){
console.log('我是中间层')
}
function handle3(){
console.log('我是最里层')
}
</script>
示例2:只将中间层div2绑定为捕获事件,那么触发顺序为:中间—>内层—>外层
示例3:只将最内层div3绑定为捕获事件,那么触发顺序为:内层—>中间----->外层
示例4:将最外层div1和中间层div2都绑定为捕获事件,那么触发顺序为:外层—>中间---->内层
1、在JavaScript中,事件默认是按照事件冒泡的方式传递的。
2、可以通过addEventListener方法的第三个参数来指定事件是按照事件捕获还是事件冒泡进行传递的。
3、true:表示事件按照事件捕获方式传递。
4、false:或不指定该参数,则表示事件按照事件冒泡方式传递。
注意:
1、vue中,元素使用@click绑定点击事件,默认冒泡,可以使用.capture修改为捕获阶段。
2、纯js中,使用onclick绑定点击事件,默认冒泡阶段触发,但是无法使用.capture,
只能使用addEventListener绑定事件,修改为捕获阶段。