事件捕获和冒泡

众所周知(假装是这样的),在IE(支持冒泡)和NetScape(支持捕获)两者打完之后,W3C给了个折中的结果“先捕获再冒泡,就这么定了”。

所以事件的触发会经历三个阶段:
  1. 事件捕获阶段(e.eventPhase==1)从document开始,一层层往里面捕获,遇到捕获事件立即触发执行;
  2. 处于目标阶段(e.eventPhase==2)到达事件位置,触发事件;
  3. 事件冒泡阶段(e.eventPhase==3)从事件位置一层层往外冒泡,直到返回到document,遇到冒泡事件立即触发执行。

obj.addEventListener(“click”,func, true); //捕获方式
obj.addEventListener(“click”,func, false);//冒泡方式

再来看下event.stopPropagation()到底是个什么鬼。

说是阻止冒泡,然而并不严谨昂~,因为它不只是阻止冒泡,还阻止事件的继续捕获,说白了就是不让事件继续传播了呢。当然不传播不代表当前节点的其他事件也不执行,如果想要接下来绑定在该节点的其他事件也阻止的话,就要用event.stopImmediatePropagation()来阻止(这么多额,真是烦躁)。

还有更烦躁的,捕获和冒泡的顺序是严格的,所以事件之间的执行顺序和事件注册的顺序是没关系的。
但是!如果一个节点既绑定了捕获事件,又绑定了冒泡事件,并且都处于eventPhase==2 && e.target==e.currentTarget的阶段,那么就和注册顺序保持一致。这个时候就要看事件发生的位置和阶段了,不要忽略不要忽略不要忽略,点击一个div的时候最先进行的处理是判断e.targete.currentTarget是否相等。
比如我按照这样的顺序写了代码:

parent

child

我点击child的时候,控制台输出的是什么呢。。。


事件捕获和冒泡_第1张图片

所以点击child的时候父元素不处于phase2,所以父元素身上的事件就是最先捕获,最后冒泡。但对于child元素来说,event的currentTarget就是child本身,而我先注册了冒泡后注册的捕获,所以child就得乖乖先冒泡后捕获。。。
是不是觉得很晕的说。。。

further more 浏览器宝宝为我们提供了一个获取节点事件数的方法(如论是什么方式的绑定,addEventListener也算,onclick=‘func()’也算):getEventListeners(node),返回一个事件数组。

事件捕获和冒泡_第2张图片

如果注册事件类型不一样,返回不同数组:
事件捕获和冒泡_第3张图片

比如这里有三个click事件和一个 mousedown事件。

你可能感兴趣的:(事件捕获和冒泡)