冒泡:做用于子元素上的事件会一级一级向上传递,相似于冒泡的形式。
捕获:做用于父元素的事件会一级一级向下传递到最终的子元素。html
文档请参考 addEventListener,以及 runnoob的addEventListener
EventTarget.addEventListener()语法:浏览器
element.addEventListener(event, function, useCapture)
注意useCapture参数,他是一个boolean值,指定事件是否在捕获或冒泡阶段执行。默认为false,若是指定为true,代表在捕获阶段执行,指定为true,代表在冒泡阶段执行。this
先看以下代码:spa
<!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,控制台打印以下:code
能够看到第一次打印的target和currentTarget都是son,而第二次事件冒泡到了parent,此时target是son,currentTarget变成了parent。htm
咱们把代码中的useCapture改成true:blog
let pa = document.getElementById('parent'); pa.addEventListener('click', handler, true); let son = document.getElementById('son'); son.addEventListener('click', handler, true);
而后再次运行,结果如图:事件
此时事件实在捕获阶段执行,也就是说会先触发parent的click事件。图片
仔细看前面的打印信息就知道了,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呢?