冒泡和捕获
在页面中点击一个元素,事件是从这个元素的祖先元素中逐层传递下来的,这个阶段为事件的捕获阶段。当事件传递到这个元素之后,又会把事件逐成传递回去,直到根元素为止,这个阶段是事件的冒泡阶段。
如上图所示,事件传播分成三个阶段:
- 捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会响应任何事件;
- 目标阶段:在目标节点上触发,称为“目标阶段”
- 冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling phase)。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层;
我们为一个元素绑定一个点击事件的时候,可以指定是要在捕获阶段绑定或者换在冒泡阶段绑定。
HTML DOM addEventListener() 方法:
element.addEventListener(event, function, useCapture)
event | 必须。字符串,指定事件名。 注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。 提示: 所有 HTML DOM 事件,可以查看我们完整的 HTML DOM Event 对象参考手册。 |
function | 必须。指定要事件触发时执行的函数。 当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件) 对象。 |
useCapture | 可选。布尔值,指定事件是否在捕获或冒泡阶段执行。 可能值:
|
当addEventListener
的第三个参数为true
的时候,代表是在捕获阶段绑定,当第三个参数为false
或者为空的时候,代表在冒泡阶段绑定。
知道事件有这么一个穿透的过程之后,结合下面的例子,就可以很好来理解event.target
和event.currentTarget
:
<div id="a"> <div id="b"> <div id="c"> <div id="d"></div> </div> </div> </div>
<script> document.getElementById('a').addEventListener('click', function(e) { console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id); }); document.getElementById('b').addEventListener('click', function(e) { console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id); }); document.getElementById('c').addEventListener('click', function(e) { console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id); }); document.getElementById('d').addEventListener('click', function(e) { console.log('target:' + e.target.id + '¤tTarget:' + e.currentTarget.id); }); </script>
上面事件的绑定都是在冒泡阶段的,当我们点击最里层的元素d的时候,会依次输出:
target:d¤tTarget:d
target:d¤tTarget:c
target:d¤tTarget:b
target:d¤tTarget:a
从输出中我们可以看到,event.target
指向引起触发事件的元素,而event.currentTarget
则是事件绑定的元素,只有被点击的那个目标元素的event.target
才会等于event.currentTarget
。
如果我们把事件都绑定在捕获阶段,然后还是点击最里层的元素d,这时event.target
还依旧会指向d,因为那是引起事件触发的元素,因为event.currentTaget
指向事件绑定的元素,所以在捕获阶段,最先来到的元素是a,然后是b,接着是c,最后是d。所以输出的内容如下:
target:d¤tTarget:a
target:d¤tTarget:b
target:d¤tTarget:c
target:d¤tTarget:d
参考:https://www.cnblogs.com/yzhihao/p/9398917.html
参考:https://www.runoob.com/jsref/met-element-addeventlistener.html