Open Twlig opened 2 years ago
当点击一个按钮时,实际上不光点击了这个按钮,还点击了它的容器以及整个页面。那么如何获取事件的发生先后顺序,就反映了事件流。
事件流描述了页面接收事件的顺序。有事件冒泡和事件捕获两种。
事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。
如:
<!DOCTYPE html> <html> <head> <title>Event Bubbling Example</title> </head> <body> <div id="myDiv">Click Me</div> </body> </html>
在点击页面中的<div>元素后,click 事件会以如下顺序发生:
<div>
click
1. <div> 2. <body> 3. <html> 4. document
<div>元素,即被点击的元素,最先触发 click 事件。然后,click 事件沿 DOM 树一路向上,在经过的每个节点上依次触发,直至到达 document 对象。
最不具体的节点最先收到事件,而最具体的节点最后收到事件。事件捕获实际上是为了在事件到达最终目标 前拦截事件。
如果前面的例子使用事件捕获,则点击<div>元素会以下列顺序触发 click 事件:
1. document 2. <html> 3. <body> 4. <div>
在事件捕获中,click 事件首先由 document 元素捕获,然后沿 DOM 树依次向下传播,直至到达实际的目标元素<div>。
通常建议使用事件冒泡,特殊情况下可以使用事件捕获。
DOM2 Events 规范规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。
✨注意:
由于存在事件冒泡,注册点击事件的顺序无关,只和事件冒泡的顺序有关,从内到外
document.body.onclick = function(event) { console.log("Body clicked"); }; btn.onclick = function(event) { console.log("Clicked"); }; //Clicked //Body clicked //事件触发和注册点击事件的顺序无关,只和事件冒泡的顺序有关,从内到外,先btn触发,再是body
插播一个阻止冒泡的方法stopPropagation()
stopPropagation()
let btn = document.getElementById("myBtn"); btn.onclick = function(event) { console.log("Clicked"); event.stopPropagation(); //阻止事件冒泡,body点击事件无法触发 }; document.body.onclick = function(event) { console.log("Body clicked"); }; //Clicked
✨补充:
大多数事件都支持冒泡,但是还有少数事件不支持:
这些事件仅发生于自身上,而它的任何父节点上的事件都不会产生,所有不会冒泡。
当点击一个按钮时,实际上不光点击了这个按钮,还点击了它的容器以及整个页面。那么如何获取事件的发生先后顺序,就反映了事件流。
事件冒泡
事件被定义为从最具体的元素(文档树中最深的节点)开始触发,然后向上传播至没有那么具体的元素(文档)。
如:
在点击页面中的
<div>
元素后,click
事件会以如下顺序发生:<div>
元素,即被点击的元素,最先触发 click 事件。然后,click 事件沿 DOM 树一路向上,在经过的每个节点上依次触发,直至到达 document 对象。事件捕获
最不具体的节点最先收到事件,而最具体的节点最后收到事件。事件捕获实际上是为了在事件到达最终目标 前拦截事件。
如果前面的例子使用事件捕获,则点击
<div>
元素会以下列顺序触发 click 事件:在事件捕获中,click 事件首先由 document 元素捕获,然后沿 DOM 树依次向下传播,直至到达实际的目标元素
<div>
。通常建议使用事件冒泡,特殊情况下可以使用事件捕获。
事件流
DOM2 Events 规范规定事件流分为 3 个阶段:事件捕获、到达目标和事件冒泡。
✨注意:
由于存在事件冒泡,注册点击事件的顺序无关,只和事件冒泡的顺序有关,从内到外
插播一个阻止冒泡的方法
stopPropagation()
✨补充:
大多数事件都支持冒泡,但是还有少数事件不支持:
这些事件仅发生于自身上,而它的任何父节点上的事件都不会产生,所有不会冒泡。