冒泡和捕获的执行顺序
冒泡机制的执行顺序是自下往上的,当目标元素绑定的事件被触发时,事件会从目标元素自下向上依次执行。
捕获机制的执行顺序是自上往下的,当目标元素绑定的事件被触发时,事件会从 DOM 树最顶层自上向下依次执行,直到执行到目标元素为止。
关于执行次数
DOM0
DOM0 级事件具有极好的跨浏览器优势,会以最快的速度绑定。
为某一个元素的同一个行为绑定不同的方法在行内会分别执行。
为某一个元素的同一个行为绑定不同的方法在 script 标签中后面的方法会覆盖前面的方法。
<div id="box" onclick="fun1();fun2()">点我</div>
<script>
// 某一个元素的同一个行为绑定不同的方法在行内会分别执行
function fun1() {
console.log("方法1")
}
function fun2() {
console.log("方法2")
}
// 执行 方法1 // 执行方法2
</script>
<div id="box">点我</div>
<script>
// 某一个元素的同一个行为绑定不同的方法在script标签中后面的方法会覆盖前面的方法
var box = document.getElementById("box")
box.onclick = fun1
box.onclick = fun2
function fun1() {
console.log("方法1")
}
function fun2() {
console.log("方法2")
}
// 执行方法2;方法2覆盖方法1,所有方法1不执行
</script>
删除 DOM 0 事件处理程序,只要将对应事件属性设为 null 即可。
box.onclick = null;
DOM2
DOM2级事件是通过addEventListener绑定的事件,IE下的DOM2事件通过attachEvent绑定;可以给某一个元素的同一个行为绑定不同的方法在行内会分别执行。
addEventListener 函数的第三个参数设置为 false,说明为该元素绑定的事件使用冒泡机制;为true则表示使用捕获机制。
<div id="box">点我</div>
<script>
var box = document.getElementById('box');
box.addEventListener('click', fun1,false);
box.addEventListener('click', fun2,false);
function fun1() {
console.log('方法1');
}
function fun2() {
console.log('方法2');
}
// 执行方法1 // 执行方法2
</script>
删除DOM 2事件处理程序,通过removeEventListener
box.removeEventListener('click', fun2,false);
关于多个事件的执行顺序
当一个元素绑定了两个事件,一个是冒泡,一个是捕获。
该 DOM 上的事件如果被触发,执行顺序会按照下边的规则执行:
如果该 DOM 是目标元素,则按事件绑定顺序执行,不区分冒泡还是捕获【新版浏览器实验显示:目标元素事件区分冒泡和捕获,执行顺序都是先捕获、后冒泡,无视目标元素事件绑定顺序】
如果该 DOM 是处于事件流中的非目标元素,则先执行捕获后执行冒泡。因为 W3C 标准有说明,先发生捕获事件,后发生冒泡事件。
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', function(){
console.log('bubble','btn');
},false);
btn.addEventListener('click', function(){
console.log('capture','btn');
},true);
div.addEventListener('click', function(){
console.log('bubble','div');
},false);
div.addEventListener('click', function(){
console.log('capture','div');
},true);
// 打印顺序是: 1、capture div 2、capture btn 3、bubble btn 4、bubble div