那天面试应届生,问了一下 Javascript 的事件机制,发现自己对于这块,有点不能确认了,这里来理了一下整个事件机制,彻底研究了下整改过程。发现对于这种东西,不经常用,就会忘记。还是要多复习,温故而知新,才能不断成长。
Javscript 事件捕捉、 事件冒泡
事件是监听在某个DOM元素上的,但是js的DOM事件有捕获和冒泡的机制,所以事件处理不是我们想的那样简单
由于存在捕获和冒泡,所以事件的触发元素(目标源)不一定是当前的监听元素。于是就有一些问题,本文要解决的就是将这些问题整理叙述清楚。
事件流
首先我们要理解事件流,即JavaScript中,事件触发的这一系列的流程

事件捕获 (event capturing)
事件捕获过程中,document 对象首先接收到click事件,然后事件沿DOM树依次向下,一直到事件的实际目标,既div元素
Html
1 | <body> |
Js
1 | var parent = document.getElementById('parent'); |
点击后打印结果为
1 | parent |
Js
1 | var parent = document.getElementById('parent'); |
点击后打印结果为
1 | child |
一般我们都不会传入第三个参数,第三个参数默认一般也都是false,也就是事件冒泡
实践
实现将一个功能,点击按钮,就可以弹出一个选择框,在我点击非选择框区域的时候,选择框就会自动消失。
1 | <div id="wrapper" class="wrapper"> |
第一次可能我会这样实现
1 | button.addEventListener('click', function(e){ |
这里当我们点击按钮之后,看上去什么都没有发生。这是为什么呢?那是因为在事件冒泡阶段,执行完第一个按钮点击事件后,继续向上冒泡,遇到了document的点击事件,于是又执行了,这样弹窗又再次隐藏了。
很简单的思路是,我们让执行完第一个事件之后,不再冒泡了,事件冒泡就此断开。
1 | button.addEventListener('click', function(e){ |
