目录
- 事件流
- 总结:
- 事件捕获
- 示例:
- 事件冒泡
- 阻止冒泡(阻断事件流动传播,不止在冒泡阶段有效,捕获阶段也有效)
- 解绑事件
- 鼠标经过事件的区别:
事件流
-
事件流指的是事件完整执行过程中的流动路径。
-
事件流是对事件执行过程的描述,了解事件的执行过程有助于加深对事件的理解,提升开发实践中对事件运用的灵活度。
-
任意事件被触发时总会经历两个阶段:捕获阶段和冒泡阶段。
简言之,捕获阶段是从父到子的传导过程,冒泡阶段是从子向父的传导过程。
-
结合事件流的特征,我们知道当某个元素的事件被触发时,事件总是会先经过其祖先才能到达当前元素,然后再由当前元素向祖先传递,事件在流动的过程中遇到相同的事件便会被触发。
-
事件的执行顺序是可控制的,即可以在捕获阶段被执行,也可以在冒泡阶段被执行。
-
如果事件是在冒泡阶段执行的,我们称为冒泡模式,它会先执行子盒子事件再去执行父盒子事件,默认是冒泡模式。
-
如果事件是在捕获阶段执行的,我们称为捕获模式,它会先执行父盒子事件再去执行子盒子事件。
总结:
addEventListener
第3个参数决定了事件是在捕获阶段触发还是在冒泡阶段触发addEventListener
第3个参数为 true 表示捕获阶段触发,false 表示冒泡阶段触发,默认值为 false- 事件流只会在父子元素具有相同事件类型时才会产生影响
- 绝大部分场景都采用默认的冒泡模式(其中一个原因是早期 IE 不支持捕获)
事件捕获
- 概念:从DOM的根元素开始去执行对应的事件(从外到里)
- 事件捕获需要对应代码才能看到效果
- 代码:
DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
- 说明:
addEventListener
第三个参数传入ture
代表是捕获阶段触发(很少使用)- 若传入
false
代表冒泡阶段触发,默认是false
示例:
点击son
的盒子部分,会依次显示:
<div class="father"><div class="son"></div></div><script>const fa = document.querySelector('.father')const son = document.querySelector('.son')document.addEventListener('click', function () {alert('grandpa')}, true)fa.addEventListener('click', function () {alert('father')}, true)son.addEventListener('click', function () {alert('son')}, true)</script>
<style>.father {width: 300px;height: 200px;background-color: aquamarine;}.son {width: 100px;height: 50px;background-color: bisque;}</style>
事件冒泡
- 概念:当一个元素的事件被触发时,同样的事件会在该元素的所有祖先元素中依次触发。
即:当一个元素触发事件后,会依次向上调用所有父级元素的同名事件 - 事件冒泡是默认存在的
- L2事件监听第三个参数是false,或者默认都是冒泡
案例只要把上面事件捕获代码的true
删除就行。
阻止冒泡(阻断事件流动传播,不止在冒泡阶段有效,捕获阶段也有效)
- 前提:阻止事件冒泡需要拿到事件对象
- 语法:
事件对象.stopPropagation()
- 此方法可以阻断事件流动传播,不止在冒泡阶段有效,捕获阶段也有效
son.addEventListener('click', function (e) {alert('son')// 阻止流动传播e.stopPropagation()})
解绑事件
- on事件方式,直接使用null覆盖就可以实现
<button>click</button>
<script>const btn=document.querySelector('button')btn.onclick=function(){alert('click')btn.onclick=null}
</script>
- addEventListener方式,必须使用:
removeEventListener(事件类型,事件处理函数,[获取捕获或者冒泡阶段])
[]代表可以省略
注意:匿名函数无法被解绑
<button>click</button><script>const btn = document.querySelector('button')function fn() {alert('click')}btn.addEventListener('click', fn)// L2事件移除btn.removeEventListener('click', fn)
鼠标经过事件的区别:
mouseover
和mouseout
会有冒泡效果mouseenter
和mouseleave
没有冒泡效果 (推荐)