一、什么是事件冒泡
事件是用于触发js代码的某种状态或行为,是html实现与js交互的桥梁。事件必须被安装在某个对象上,比如浏览器或文档中的元素,否则事件就无法存在。设想如果不把click()或mousemove()这样的事件绑定到某个对象(事件目标event target)上,那么无论鼠标怎么点怎么滑,网页都不会有任何反应。于是问题来了,当某个事件发生的时候,浏览器如何判断这个事件发生在谁身上呢?比如点击son区域,那究竟是点的son,还是Dad,还是Grandpa?由于html中存在大量嵌套关系,因此必须规定某种顺序去查询究竟是谁绑定了这个事件,从而才能触发相应的js。这个顺序被称为“事件流”,而事件冒泡就是事件流的一种类型。
二、事件流的三种类型
1、事件冒泡。从事件发生的最具体的节点开始,沿着DOM树向上依次查询,直到body、html和document。仍以上图为例,如果Grandpa绑定了一个click事件,点击Grandpa中间区域,浏览器并不是直接触发Grandpa的事件,浏览器只知道son被点中了,于是开始查询:son有没有绑定click、Dad有没有绑定click、Grandpa有没有绑定click……document有没有绑定click。在同一条DOM血缘关系链上所有元素都会被检查一遍,其中所有的click都会被触发。
2、事件捕获。与事件冒泡刚好相反,不具体展开。
3、DOM事件流。DOM事件流规定了三个阶段:捕获,目标和冒泡。至于为啥要这样设计,在《JavaScript高级程序设计》和《JavaScript权威指南》中我都没查到。因此有待进一步考证。
三、事件委托
利用事件冒泡,将事件绑定在父元素上,这样所有子元素都可以利用父元素的事件来触发js代码的执行,这就是事件委托(或称为事件代理)。相比于给每个元素单独添加同样的事件,这么做的好处是内存消耗更小。
四、阻止冒泡
使用stopPropagation()可以阻截事件冒泡。
如果不阻止,点击son区域,浏览器会依次弹出三个框,阻止冒泡后,就只会出现一次:
五、哪些事件支持冒泡,哪些不支持
待续……