1、事件阶段
如下图所示
(1)捕获阶段(Capture Phase)
事件的第一个阶段是捕获阶段。事件从文档的根节点流向目标对象节点。途中经过各个层次的DOM节点,并在各节点上触发捕获事件,直到到达事件的目标节点。捕获阶段的主要任务是建立传播路径,在冒泡阶段,事件会通过这个路径回溯到文档跟节点。
(2)目标阶段(Target Phase)
当事件到达目标节点的,事件就进入了目标阶段。事件在目标节点上被触发,然后会逆向回流,直到传播至最外层的文档节点。
(3)冒泡阶段(Bubble Phase)
事件在目标元素上触发后,并不在这个元素上终止。它会随着DOM树一层层向上冒泡,回溯到根节点。
冒泡过程非常有用。它将我们从对特定元素的事件监听中释放出来,如果没有事件冒泡,我们需要监听很多不同的元素来确保捕获到想要的事件。2、冒泡阶段调用事件处理函数
3、捕获阶段调用事件处理函数
4、事件代理
在传统的事件处理中,你按照需要为每一个元素添加或者是删除事件处理器。然而,事件处理器将有可能导致内存泄露或者是性能下降——你用得越多这种风险就越大。JavaScript事件代理可以把事件处理器添加到一个父元素上,这样就避免了把事件处理器添加到多个子元素上。
(1)它是怎么运作的呢?
事件代理用到了两个JavaSciprt事件特性:事件冒泡以及目标元素。当一个元素上的事件被触发的时候,同样的事件将会在那个元素的所有祖先元素中被触发。这一过程被称为事件冒泡;使用事件代理,我们可以把事件处理器添加到一个元素上,等待一个事件从它的子级元素里冒泡上来,并且可以得知这个事件是从哪个元素开始的。
(2)这对我有什么好处呢?
比如说在一个10列、100行的HTML表格里,让其每一个单元格在被点击的时候变成可编辑状态。如果把事件处理器加到这1000个单元格会产生一个很大的性能问题,并且有可能导致内存泄露甚至是浏览器的崩溃。相反地,使用事件代理,你只需要把一个事件处理器添加到table元素上就可以了,这个函数可以把点击事件给截下来,并且判断出是哪个单元格被点击了。
(3)另一个简单的例子
5、阻止事件冒泡(stopPropagation)
(1)为什么要阻止事件冒泡
有种可能是,某个DOM节点绑定了某事件监听器,本来是想当该DOM节点触发事件,才会执行回调函数。结果是该节点的某后代节点触发某事件,由于事件冒泡,该DOM节点事件也会触发,执行了回调函数,这样就违背了最初的本意了。
(2)如何阻止事件冒泡
(3)无法在捕获阶段阻止事件冒泡
这里需要注意的是,我们无法在事件捕获阶段阻止事件冒泡!!!例如,我们在代码里加上true,如图所示,第一个li会触发事件。因为捕获是从根节点向目标节点触发,而冒泡是从目标节点向根节点触发。