JS之事件捕获和事件冒泡
DOM事件流(event flow )存在三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段。
事件捕获(event capturing)
: 当鼠标点击或者触发dom事件时(被触发dom事件的这个元素被叫作事件源),浏览器会从根节点 =>事件源(由外到内)进行事件传播。
事件冒泡(dubbed bubbling)
: 事件源 =>根节点(由内到外)进行事件传播。
无论是事件捕获还是事件冒泡,它们都有一个共同的行为,就是事件传播。
dom标准事件流的触发的先后顺序为:先捕获再冒泡。即当触发dom事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。
addEventListener的第三个参数
在我们平常用的addEventListener方法中,一般只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数,然而,addEventListener还可以传入第三个参数:
element.addEventListener(event, function, useCapture);
第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果参数为true,则表示在事件捕获阶段调用处理函数。
事件冒泡举例
<div id="parent">父元素 <div id="child">子元素</div> </div> <script> let oParent = document.getElementById('parent') let oChild = document.querySelector('#child') document.body.addEventListener('click', function () { console.log('body click') }, false) oParent.addEventListener('click', function () { console.log('parent click') }, false) oChild.addEventListener('click', function () { console.log('child click') }, false) </script>
点击打印
事件捕获
<div id="parent">父元素 <div id="child">子元素</div> </div> <script> let oParent = document.getElementById('parent') let oChild = document.querySelector('#child') document.body.addEventListener('click', function () { console.log('body click') }, false) oParent.addEventListener('click', function () { console.log('parent click') }, false) oChild.addEventListener('click', function () { console.log('child click') }, false) oParent.addEventListener('click', function () { console.log('parent click --事件捕获') }, true) oChild.addEventListener('click', function () { console.log('child click--事件捕获') }, true) </script>
父元素通过事件捕获的方式注册了click事件,所以在事件捕获阶段就会触发,然后到了目标阶段,即事件源,之后进行事件冒泡,parent同时也用冒泡方式注册了click事件,所以这里会触发冒泡事件,最后到根节点(body)。这就是整个事件流程。