花一天时候研讨完了DOM2级事宜中addEventListener的实行机制,作为开山第一帖,和人人讲讲多个addEventListener同时增加时的实行前后规律:
如图,人人都晓得,W3c的DOM事宜触发分为三个阶段:
①、事宜捕捉阶段,即由最顶层元素(平常是从window元素最早,有的浏览器是从document最早,至于个中的差异我稍后会更新)最早,逐次进入dom内部,末了抵达目的元素,顺次实行绑定在其上的事宜
②、处于目的阶段,检测机制抵达目的元素,按事宜注册递次实行绑定在目的元素上的事宜。
③、事宜冒泡阶段,从目的元素动身,向外层元素冒泡,末了抵达顶层(window或document),顺次实行绑定再其上的事宜。
在addEventListener中,应用第三个参数掌握其是从哪一个阶段最早,“true”是从捕捉阶段最早,而“false”则是跳过捕捉阶段,从冒泡阶段最早。
看一个简朴的例子:
<script type="text/javascript">
window.onload=function(){
var outer = document.getElementById("outer");
var inner = document.getElementById('inner');
outer.addEventListener("click", function(){
alert("1");
}
, true);
inner.addEventListener("click", function(){
alert("2");
}
, true);
outer.addEventListener("click",
function(){
alert("3");
}
,false)
}
</script>
<body>
<div id="outer">
<div id="inner"></div>
</div>
</body>
在这个例子里,假如我们点击内层元素inner,那末处于捕捉阶段的1最早弹出,接下来是目的元素2弹出,末了是处于冒泡阶段的3弹出,即:1,2,3.
纵然在代码里变更三个绑定事宜的递次,只需点击的是inner,这个实行递次就不会变。
那末题目来了,假如点击的是外层outer的话呢?
要邃晓这个题目,我们必需明白一点:目的事宜在哪一层,事宜流就在哪一层回流,纵然在outer事宜下另有很多子孙节点,事宜流都不会在outer以后往内流,此时,inner上的事宜不会被触发,因而在这段代码中,只会弹出1和3。
那末这两个数字哪一个先弹呢?因为此时事宜处于第二阶段,即“处于目的阶段”,弹出递次取决的也不再是捕捉或冒泡,而是谁在代码中先注册,因而,在这段代码中,弹出的是:1→3.
综上所述,事宜在DOM中的实行递次为:外层捕捉事宜→内层捕捉事宜→先注册的目的事宜→后注册的目的事宜→内层冒泡事宜→外层冒泡事宜
让我们再看个例子来加深这个观点:
<script type="text/javascript">
window.onload=function(){
var outer = document.getElementById("outer");
var inner = document.getElementById('inner');
var oBox=document.getElementById('box');
oBox.addEventListener("click",function(){
alert('1');
},true)
oBox.addEventListener("click",function(){
alert('4');
},false)
outer.addEventListener("click", function(){
alert("2");
}, true);
inner.addEventListener("click",function(){
alert('3.2')
},false)
inner.addEventListener("click", function(){
alert("3.1");
}, true);
}
</script>
<body>
<div id="box">
<div id="outer">
<div id="inner"></div>
</div>
</div>
</body>
在这段代码里,box上的捕捉事宜最早实行,然后是outer上的捕捉事宜,然后是inner上先注册的事宜,然后是inner上后注册的事宜,末了是box上的冒泡事宜
弹出递次为:1→2→3.2→3.1→4
补充一点,在ie8-中,因为addEventLister不起作用,我们运用attachEvent方法来绑定事宜,此时在第二阶段,也就是处于目的阶段,假如目的元素上绑定了两个事宜,那末其实行递次和addEventLister相反:谁后注册谁先实行。