详解addEventListener() 捕获与冒泡
这篇笔记存在未证实的知识待处理(目标阶段的捕获和冒泡是否有用问题)
addEventListener的三个值
1值 事件名称(事件类型)注意不加on
2值 处理函数 可以写多个处理程序
3值 使用时true表示在捕获阶段触发 默认为false 为冒泡阶段触发
在最底层(目标阶段)上一层 添加addEventListen的第三个值
以下运行结果为:div捕获>btn1>btn2>btn3>div冒泡
如果该div不添加第三个值 运行结果为:btn1>btn2>btn3>div捕获>div冒泡
<!-- html代码: -->
<div>
<button id="btn1">点击1</button>
</div>
// js代码:
// 得到button并给button注册点击事件 同时写入多个处理事件
var btn = document.getElementById("btn1");
btn.addEventListener("click", function () { //处理程序1
console.log("btn1");
});
btn.addEventListener("click", function () { //处理程序2
console.log("btn2");
}
btn.addEventListener("click", function () { //处理程序3
console.log("btn3");
});
// 给button父级div注册点击事件 同时写入多个处理事件
document.querySelector("div").addEventListen("click", function () { //处理程序4
console.log("div 捕获");
}, true)
document.querySelector("div").addEventListen("click", function () { //处理程序5
console.log("div 冒泡");
}, false)
当在目标阶段使用捕获和冒泡
运行规则:
目标阶段中有处理程序设置为(捕获)true 那么会先运行该处理程序
注意1 只会在目标阶段内最前面运行 不会跑到外层(如父级以上)
注意2 如果在同一阶段有多个处理程序同设置为(捕获)true 那么会按照注册顺序依次执行
以下运行结果为:div捕获>btn2>btn3>btn1>div冒泡 浏览器 google Edge 有效
如果不是以上结果那么以上运行规则全作废 火狐 IE浏览器中 目标阶段(最里层)不存在捕获和冒泡 执行规则为注册先后
运行结果为:div捕获>btn1>btn2>btn3>div冒泡
btn.addEventListener("click", function () { //处理程序1
console.log("btn1");
}, false);
btn.addEventListener("click", function () { //处理程序2
console.log("btn2");
}, true)
btn.addEventListener("click", function () { //处理程序3
console.log("btn3");
}, true);
document.querySelector("div").addEventListen("click", function () { //处理程序4
console.log("div1 捕获");
}, true)
document.querySelector("div").addEventListen("click", function () { //处理程序5
console.log("div2 冒泡");
}, false)
总结
- 默认运行规则为 冒泡规则 从里层到外层
设为捕获规则时 捕获规则 从外层到里层 - 执行多个同一元素事件时,按照注册顺序执行
执行不同的元素事件时,按照事件流的顺序执行(默认情况为冒泡) - 阶段之间不会逾越
例如:有两个嵌套div 父级为div1子级为div2 两者都设为捕获 即使子级注册在前但最先执行的还是父级
该前提是在带有层级关系并同时都设置了捕获的情况下的规则
父级未设置捕获下 按照默认情况冒泡规则运行,最先运行的是子级运行完子级内所有的程序才会执行父级 - 在目标阶段(最里层)使用冒泡和捕获要看使用的浏览器
当前测试结果为:在google、Edge运行可以。 火狐、IE运行目标阶段只按照注册顺序执行 捕获冒泡无效果