JS之event flow
DOM事件流
1.定义:
DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素节点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。DOM事件流最独特的性质是,文本节点也触发事件(在IE中不会),当鼠标单击“单击此文本”文本时会触发click事件,该事件的捕获阶段最先开始,从Document节点开始逐渐向下传播,直到“单击此文本”文本节点,事件进入目标阶段,在目标阶段结束之后,事件由“单击此文本”文本节点开始事件的冒泡阶段,直到Document节点为止。
2.两种事件流:
冒泡型事件流:事件的传播是从最特定的事件目标到最不特定的事件目标。即从DOM树的叶子到根。
捕获型事件流:事件的传播的英文从最不特定的事件目标到最特定的事件目标。即从DOM树的根到叶子。
1 <模板> 2 <div id =“div1”style =“width:200px; height:200px;” V-上:click.capture = “迎接( '1',$事件)”> 3 <div id =“div2”style =“width:150px; height:150px;” V-上:click.capture = “迎接( '2',$事件)”> 4 <div id =“div3”style =“width:100px; height:100px;” V-上:click.capture = “迎接( '3',$事件)”> 3 </ DIV> 5 </ DIV> 6 </ DIV> 7 </模板> 8 9 <SCRIPT> 10 从“vue”导入Vue; 11 export default { 12 名字:'你好', 13 data(){ 14 返回{ 15 名称:'Vue.js' 16 } 17 }, 18 方法:{ 19 greet:function(msg,e){ 20 执行console.log(味精) 21 } 22 } 23 } 24 </ SCRIPT> 25 26 <! - 添加“scoped”属性以仅将CSS限制为此组件 - > 27 <style scoped> 28 DIV { 29 border:1px#333 solid 30 } 31 </样式>
输出:
3.process
事件如何通过DOM树传播。应用程序可以使用该dispatchEvent()
方法调度事件对象,并且事件对象将通过DOM事件流确定的DOM树传播。
使用DOM事件流在DOM树中调度的事件的图形表示
事件对象被分派到事件目标。但是在发送开始之前,必须首先确定事件对象的传播路径。传播路径是的有序列表的当前事件的目标,通过该事件传递。该传播路径反映了文档的分层树结构。列表中的最后一项是事件目标,列表中的前面项目称为目标的祖先,前面的项目作为目标的父项。一旦确定了传播路径,事件对象就会经过一个或多个事件阶段。有三个事件阶段:捕获阶段,目标阶段和泡沫阶段。事件对象完成这些阶段,如下所述。如果不支持某个阶段,或者事件对象的传播已停止,则将跳过该阶段。例如,如果bubbles
属性设置为false,则将跳过气泡阶段,如果stopPropagation()
在分派之前调用,则将跳过所有阶段。
(1)捕获阶段:事件对象通过目标的祖先从传播窗口到目标的父,即事件从目标节点自上而下向Document节点传播的阶段。
(2)目标阶段:本次活动对象到达事件对象的事件的目标。如果事件类型指示事件未冒泡,则事件对象将在此阶段完成后暂停,即事件从目标节点自上而下向Document节点传播的阶段。
(3)冒泡阶段:事件对象通过目标的祖先中传播以相反的顺序,开始与目标的父和与所述结束窗口,即事件从目标节点自上而下向Document节点传播的阶段。
4.method:
语法:
element.addEventListener(event, function, useCapture)
参数 | 描述 |
---|---|
event | 必需。描述事件名称的字符串。 注意: 不要使用 "on" 前缀。例如,使用 "click" 来取代 "onclick"。 提示: 所有 HTML DOM 事件,可以查看我们完整的 HTML DOM Event 对象参考手册。 |
function | 必需。描述了事件触发后执行的函数。 当事件触发时,事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件) 对象。 |
useCapture | 可选。布尔值,指定事件是否 在捕获或冒泡阶段执行。 可能值:
|
5.applicants:
1 <!DOCTYPE html> 2 <head> 3 <meta charset="UTF-8"> 4 <title>DOM事件流</title> 5 </head> 6 <body> 7 <div id="div1"> 8 <button id="btn">按钮</button> 9 </div> 10 <script> 11 var btn = document.getElementById("btn"); 12 var div1 = document.getElementById("div1"); 13 14 //事件目标 15 btn.onclick = function(){ 16 console.debug("目标1.Click btn"); 17 } 18 btn.addEventListener("click",function(){ 19 console.debug("目标2.Click btn"); 20 },true); 21 22 //事件冒泡 23 div1.onclick = function(){ 24 console.debug("冒泡1.Click div1"); 25 } 26 document.body.onclick = function(){ 27 console.debug("冒泡2.Click Body"); 28 } 29 document.onclick = function(){ 30 console.debug("冒泡3.Click document"); 31 } 32 window.onclick = function(){ 33 console.debug("冒泡4.Click window"); 34 } 35 36 //事件捕获 37 window.addEventListener("click",function(){ 38 console.debug("捕获4.Click window"); 39 },true); 40 document.addEventListener("click",function(){ 41 console.debug("捕获3.Click document"); 42 },true); 43 document.body.addEventListener("click",function(){ 44 console.debug("捕获2.Click body"); 45 },true); 46 div1.addEventListener("click",function(){ 47 console.debug("捕获1.Click div1"); 48 },true); 49 50 </script> 51 </body> 52 </html>
1 document.body.addEventListener("click",function(){ 2 console.debug("捕获2.Click body"); 3 },true);
addEventListener用于注册事件的处理器,当添加了第三个参数为true时,代表了在捕捉阶段接受后代元素的事件。
点击button按钮后,结果如下
1 event.html:38 捕获4.Click window 2 event.html:41 捕获3.Click document 3 event.html:44 捕获2.Click body 4 event.html:47 捕获1.Click div1 5 event.html:16 目标1.Click btn 6 event.html:19 目标2.Click btn 7 event.html:24 冒泡1.Click div1 8 event.html:27 冒泡2.Click Body 9 event.html:30 冒泡3.Click document 10 event.html:33 冒泡4.Click window
由此可见DOM事件流的顺序是
1.捕获
window
document
body
div1
2.目标 (目标的顺序与事件定义的先后顺序有关)
目标一
目标二
3.冒泡
div1
body
document
window
应用场景
以上面的例子为例,想要触发在button上的事件,但是不想触发在div和其上元素的事件时,弄清事件流就相当重要。比如:阻止事件冒泡过程,防止事件冒泡而带来不必要的错误和困扰。 这个方法就是:stopPropagation() 对button的click事件做一些改造。