我的回答
浏览器事件流分为3个大的阶段
- 事件捕获
- 事件目标
- 事件冒泡
参考回答
事件流向
捕获阶段
当我们对DOM元素进行操作时,比如鼠标点击,就会有一个事件传输到这个DOM元素,这个事件从Window开始,依次经过document、html、body,再不断经过子节点直到到达目标元素,从Window到达目标元素父节点的过程成为 捕获阶段,需要注意的是 此时还未到达目标节点
目标阶段
捕获阶段结束后,事件到达了目标节点的父节点,最终到达目标节点,并在目标节点上触发了这个事件,这就是目标阶段
冒泡阶段
当事件到达目标节点之后,就会沿着原路返回,这个过程有点类似水泡从水底浮出水面的过程,所以称这个过程为冒泡阶段。
代码实现的过程
通过addEvevtListener添加参数,第三个参数,表示在捕获阶段还是冒泡阶段触发
true为捕获, false为冒泡
事件从外到内捕获,然后从内到外冒泡
<body><div id="wrap"><button id="btn">click me</button></div><script>var wrap = document.getElementById("wrap");var btn = document.getElementById("btn");// 捕获阶段绑定事件window.addEventListener("click", function(e){console.log("window 捕获", e.target.nodeName, e.currentTarget.nodeName);}, true);document.addEventListener("click", function(e){console.log("document 捕获", e.target.nodeName, e.currentTarget.nodeName);}, true);document.documentElement.addEventListener("click", function(e){console.log("documentElement 捕获", e.target.nodeName, e.currentTarget.nodeName);}, true);document.body.addEventListener("click", function(e){console.log("body 捕获", e.target.nodeName, e.currentTarget.nodeName);}, true);wrap.addEventListener("click", function(e){console.log("wrap 捕获", e.target.nodeName, e.currentTarget.nodeName);}, true);btn.addEventListener("click", function(e){console.log("btn 捕获", e.target.nodeName, e.currentTarget.nodeName);}, true);// 冒泡阶段绑定的事件window.addEventListener("click", function(e){console.log("window 冒泡", e.target.nodeName, e.currentTarget.nodeName);}, false);document.addEventListener("click", function(e){console.log("document 冒泡", e.target.nodeName, e.currentTarget.nodeName);}, false);document.documentElement.addEventListener("click", function(e){console.log("documentElement 冒泡", e.target.nodeName, e.currentTarget.nodeName);}, false);document.body.addEventListener("click", function(e){console.log("body 冒泡", e.target.nodeName, e.currentTarget.nodeName);}, false);wrap.addEventListener("click", function(e){console.log("wrap 冒泡", e.target.nodeName, e.currentTarget.nodeName);}, false);btn.addEventListener("click", function(e){console.log("btn 冒泡", e.target.nodeName, e.currentTarget.nodeName);}, false);</script></body>
window 捕获 BUTTON undefineddocument 捕获 BUTTON #documentdocumentElement 捕获 BUTTON HTMLbody 捕获 BUTTON BODYwrap 捕获 BUTTON DIVbtn 捕获 BUTTON BUTTONbtn 冒泡 BUTTON BUTTONwrap 冒泡 BUTTON DIVbody 冒泡 BUTTON BODYdocumentElement 冒泡 BUTTON HTMLdocument 冒泡 BUTTON #documentwindow 冒泡 BUTTON undefined
