理解js的事件冒泡和事件捕获
定义
冒泡:作用于子元素上的事件会一级一级向上传递,类似于冒泡的形式。
捕获:作用于父元素的事件会一级一级向下传递到最终的子元素。
使用方法
文档请参考addEventListener,以及runnoob的addEventListener
EventTarget.addEventListener()语法:
element.addEventListener(event, function, useCapture)
注意useCapture参数,他是一个boolean值,指定事件是否在捕获或冒泡阶段执行。默认为false,如果指定为true,表明在捕获阶段执行,指定为true,表明在冒泡阶段执行。
案例参考
先看如下代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<style>
#parent {
height: 300px;
background-color: #bcbcbc;
}
#son {
margin-top: 100px;
height: 100px;
background-color: green;
}
</style>
</head>
<body>
<div id="parent">
我是父亲
<div id="son">我是儿子</div>
</div>
<script>
function handler(event) {
console.log('target: ', event.target);
console.log('curtrentTarget: ', event.currentTarget);
}
let pa = document.getElementById('parent');
pa.addEventListener('click', handler, false);
let son = document.getElementById('son');
son.addEventListener('click', handler, false);
</script>
</body>
</html>
使用浏览器运行这段代码,效果如下:
我们点击儿子div,控制台打印如下:
可以看到第一次打印的target和currentTarget都是son,而第二次事件冒泡到了parent,此时target是son,currentTarget变成了parent。
事件捕获
我们把代码中的useCapture改为true:
let pa = document.getElementById('parent');
pa.addEventListener('click', handler, true);
let son = document.getElementById('son');
son.addEventListener('click', handler, true);
然后再次运行,结果如图:
此时事件实在捕获阶段执行,也就是说会先触发parent的click事件。
target和currentTarget的区别
仔细看前面的打印信息就知道了,target始终不变,它代表触发事件的那个元素(不管是冒泡阶段还是捕获阶段都是指最底层的元素(这里指son)。而currentTarget则表示当前阶段注册了EventListener的元素。
如何阻止冒泡和捕获阶段事件的进一步传播
文档参考:event.stopPropagation
API用法:
event.stopPropagation()
修改我们的代码,在handler中加入event.stopPropagation():
function handler(event) {
console.log('target: ', event.target);
console.log('curtrentTarget: ', event.currentTarget);
event.stopPropagation();
}
再次运行,点击儿子div,打印出来的日志如下(冒泡阶段):
捕获阶段打印日志:
可以看到,冒泡阶段,点击事件没有继续向上传播到父元素;捕获阶段,点击事件没有继续向下传播到子元素。
P.S. 请考虑下在handler方法中,this到底指向target还是currentTarget呢?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。