首页 > 代码库 > 一个DOM元素绑定多个事件时,先执行冒泡还是捕获

一个DOM元素绑定多个事件时,先执行冒泡还是捕获

绑定在被点击元素的事件是按照代码顺序发生,其他元素通过冒泡或者捕获“感知”的事件,按照W3C的标准,先发生捕获事件,后发生冒泡事件。所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件 。

一个DOM元素绑定两个事件,一个冒泡,一个捕获,则事件会执行多少次,执行顺序如何。

首先来了解一下冒泡和捕获是怎么回事:

1.冒泡

冒泡是从下向上,DOM元素绑定的事件被触发时,此时该元素为目标元素,目标元素执行后,它的的祖元素绑定的事件会向上顺序执行。如下代码所示,四个嵌套的div:

addEventListener函数的第三个参数设置为false说明不为捕获事件,即为冒泡事件。

<div id=‘one‘>  <div id=‘two‘>    <div id=‘three‘>      <div id=‘four‘>      </div>    </div>  </div></div><script type=‘text/javascript‘>  var one=document.getElementById(‘one‘);  var two=document.getElementById(‘two‘);  var three=document.getElementById(‘three‘);  var four=document.getElementById(‘four‘);  one.addEventListener(‘click‘,function(){    alert(‘one‘);  },false);  two.addEventListener(‘click‘,function(){    alert(‘two‘);  },false);  three.addEventListener(‘click‘,function(){    alert(‘three‘);  },false);  four.addEventListener(‘click‘,function(){    alert(‘four‘);  },false);</script>

代码的执行顺序是:

点击one元素,输出one;

点击two元素,输出two one;

点击three元素,输出 three two one;

点击four元素,输出 four three two one;

2.捕获

捕获则和冒泡相反,目标元素被触发后,会从目标元素的最顶层的祖先元素事件往下执行到目标元素为止。

将上面的代码第三个参数均改为true,则执行结果如下:

点击one,输出one;

点击two,输出one two;

点击three,输出one two three;

点击four,输出one two three four;

很明显执行顺序是不同的。

 

3.当一个元素绑定两个事件,一个冒泡,一个捕获

首先,无论是冒泡事件还是捕获事件,元素都会先执行捕获阶段。

从上往下,如有捕获事件,则执行;一直向下到目标元素后,从目标元素开始向上执行冒泡元素,即第三个参数为false的绑定事件的元素。(在向上执行过程中,已经执行过的捕获事件不再执行,只执行冒泡事件。)

 如下代码:

one.addEventListener(‘click‘,function(){alert(‘one‘);},true);two.addEventListener(‘click‘,function(){alert(‘two‘);},false);three.addEventListener(‘click‘,function(){alert(‘three‘);},true);four.addEventListener(‘click‘,function(){alert(‘four‘);},false);

此时点击four元素,four元素为目标元素,one为根元素祖先,从one开始向下判断执行。

one为捕获事件,输出one;

two为冒泡事件,忽略;

three为捕获时间,输出three;

four为目标元素,开始向上冒泡执行,输出four;(从此处分为两部分理解较容易。)

three为捕获已执行,忽略;

two为冒泡事件,输出two;

one为捕获已执行,忽略。

最终执行结果为:one three four two

(在这里可能会有疑问,目标元素是什么事件有区别吗?我的测试结果是没有区别的,无论目标元素是捕获还是冒泡,在w3c下都是先从根元素执行捕获到目标元素,再从目标元素向上执行。)

例如,three作为目标元素,执行结果为:one three two(因为two是冒泡事件,在向下执行时没有执行到)。

执行次数:绑定了几个事件便执行几次。

如下代码,two元素绑定了两个不同事件,点击two都会执行这两个事件。而执行顺序有所差异

one.addEventListener(‘click‘,function(){alert(‘one‘);},true);two.addEventListener(‘click‘,function(){alert(‘two,bubble‘);},false);two.addEventListener(‘click‘,function(){alert(‘two,capture‘);},true);three.addEventListener(‘click‘,function(){alert(‘three,bubble‘);},true);four.addEventListener(‘click‘,function(){alert(‘four‘);},true);

 

1、如果two为目标元素,目标元素的事情按顺序执行,而其他元素根据W3C的标准执行,即先捕获后冒泡。

点击two执行结果:one(因为是two的父元素支持捕获事件所以先执行)  two,bubble  two,capture(顺序执行,注意逗号不是间隔,是输出内容。)

2、如果目标元素不是two,则two的两个事件按先捕获后冒泡触发执行,也就是跟前面讨论的执行过程是一样的,只不过两个事件都绑定在同一个DOM元素上。

点击three执行结果:one two,capture three,bubble two,bubble

所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件 。

一个DOM元素绑定多个事件时,先执行冒泡还是捕获