事件发生后,会在DOM树上传播,DOM事件流分为三阶段:捕获,目标,冒泡
1、捕获阶段
事件传播由目标节点的祖先节点逐级传播到目标节点。先由文档的根节点document(window)开始触发对象,最后传播到目标节点,从外向内捕获事件对象;
2、目标阶段
事件到达目标对象,事件触发,如果事件不允许冒泡,事件会在这一阶段停止传播。
3、冒泡阶段
从目标节点逐级传播到document节点。
在事件处理中目标阶段被看做冒泡阶段的一部分
如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。
EventTarget.addEventListener()
target.addEventListener(type, listener[, useCapture]);
该方法接受三个参数。
type:事件名称,大小写敏感。
listener:监听函数。事件发生时,会调用该监听函数。
useCapture:布尔值,表示监听函数是否在捕获阶段触发,默认为false(监听函数只在冒泡阶段被触发)。该参数可选。
eg.
var a = document.querySelector("#a");
var b = document.querySelector("#b");
var c = document.querySelector("#c");
//分别给a,b,c添加两个click事件的监听函数(false只在冒泡阶段触发,true在捕获阶段触发)
a.addEventListener("click", function (e) {
console.log("click a false phase:" + e.eventPhase);
});
a.addEventListener("click", function (e) {
console.log("click a true phase:" + e.eventPhase);
}, true);
b.addEventListener("click", function (e) {
console.log("click b false phase:" + e.eventPhase);
});
b.addEventListener("click", function (e) {
console.log("click b true phase:" + e.eventPhase);
}, true);
c.addEventListener("click", function (e) {
console.log("click c false phase:" + e.eventPhase);
});
c.addEventListener("click", function (e) {
console.log("click c true phase:" + e.eventPhase);
}, true);
点击div c 的运行结果:
其中,捕获阶段输出
click a true phase:1
click b true phase:1
事件沿DOM树向下传播,c 的祖先document->html->a->b
目标阶段输出
click c false phase:2
click c true phase:2
监听函数被调用的顺序按照其注册的顺序,无关第三个参数的值
冒泡阶段输出
click b false phase:3
click a false phase:3
事件沿DOM树向上传播
修改片段为
a.addEventListener("click", function (e) {
console.log("click a false1 phase:" + e.eventPhase);
});
a.addEventListener("click", function (e) {
console.log("click a false2 phase:" + e.eventPhase);
});
a.addEventListener("click", function (e) {
console.log("click a true1 phase:" + e.eventPhase);
}, true);
a.addEventListener("click", function (e) {
console.log("click a true2 phase:" + e.eventPhase);
}, true);
点击a输出为
> click a false1 phase:2
> click a false2 phase:2
> click a true1 phase:2
> click a true2 phase:2
事件从document->html->body->a->body->html->document,监听函数按照注册顺序被调用