事件流動(Event Flow):
DOM(文檔對象模型)結構是一個樹型結構,當一個HTML元素產生一個事件時,該事件會在元素節點與根結點之間的路徑傳播,路徑所經過的結點都會收到該事件,這個傳播過程可稱為DOM事件流。DOM事件流最獨特的性質是,文本節點也觸發事件(在IE中不會),當鼠標單擊“單擊此文本”文本時會觸發click事件,該事件的捕獲階段最先開始,從Document節點開始逐漸向下傳播,直到“單擊此文本”文本節點,事件進入目標階段,在目標階段結束之后,事件由“單擊此文本”文本節點開始事件的冒泡階段,直到Document節點為止。所以說,DOM事件不單單只會在一個Element上觸發,它還會流向其他Element。事件的流動通常會經歷這么三個階段;
冒泡型事件流:事件的傳播是從最特定的事件目標到最不特定的事件目標。即從DOM樹的葉子到根。
捕獲型事件流:事件的傳播的英文從最不特定的事件目標到最特定的事件目標。即從DOM樹的根到葉子。
過程(Process):
事件通過DOM樹傳播。應用程序可以使用該dispatchEvent()方法調度事件對象,并且事件對象將通過DOM事件流確定的DOM樹傳播。
事件對象被分派到事件目標。但是在發送開始之前,必須首先確定事件對象的傳播路徑。傳播路徑是的有序列表的當前事件的目標,通過該事件傳遞。該傳播路徑反映了文檔的分層樹結構。列表中的最后一項是事件目標,列表中的前面項目稱為目標的祖先,前面的項目作為目標的父項。一旦確定了傳播路徑,事件對象就會經過一個或多個事件階段。有三個事件階段:捕獲階段,目標階段和泡沫階段。事件對象完成這些階段,如下所述。如果不支持某個階段,或者事件對象的傳播已停止,則將跳過該階段。例如,如果bubbles屬性設置為false,則將跳過氣泡階段,如果stopPropagation()在分派之前調用,則將跳過所有階段。
1.捕獲階段(capture phase)
定義:事件對象在事件目標的祖先中上到下順向傳播,從最頂層的defaultView到事件目標的(直系)父元素。
捕獲階段發生在整個事件流動的開始。在這階段里事件會從父(主干)到子(分支)由上往下傳播,被元素一層層地捕獲。
2.目標階段(target phase)
定義:事件對象到達事件目標。
3。冒泡階段(bubble phase)
定義:事件對象會在事件目標的祖先元素里反向傳播,由開始的父元素到最后的defaultView(document)。
冒泡階段發生在最后,這也是我們最為熟悉的一個階段。在這階段里事件會從子(分支)到父(主干)逆向傳播,看起來像是一個水里的泡泡往上冒。
方法(Method):
語法:
element.addEventListener(event, function, useCapture)
event 必需。描述事件名稱的字符串。注意: 不要使用 "on" 前綴。例如,使用 "click" 來取代 "onclick"。
function 必需。描述了事件觸發后執行的函數。 當事件觸發時,事件對象會作為第一個參數傳入函數。 事件對象的類型取決于特定的事件。例如, "click" 事件屬于 MouseEvent(鼠標事件) 對象。
useCapture 可選。布爾值,指定事件是否 在捕獲或冒泡階段執行。可能值:true - 事件句柄在捕獲階段執行 false- 默認。事件句柄在冒泡階段執行
應用(Applications):(轉載自:https://blog.csdn.net/qq_30100043/article/details/77186811 )
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 #wrap { 10 width: 200px; 11 height: 200px; 12 background: orange; 13 } 14 #outer { 15 position: relative; 16 top: 50px; 17 left: 50px; 18 width: 100px; 19 height: 100px; 20 background: #eeddff; 21 } 22 #inner { 23 position: relative; 24 top: 25px; 25 left:25px; 26 width: 50px; 27 height: 50px; 28 background: #44ddff; 29 } 30 </style> 31 </head> 32 <body> 33 <div id="wrap"> 34 <div id="outer"> 35 <div id="inner"></div> 36 </div> 37 </div> 38 </body> 39 <script> 40 var wrap = document.getElementById('wrap'); 41 var outer = document.getElementById('outer'); 42 var inner = document.getElementById('inner'); 43 44 wrap.addEventListener('click',function(){ 45 alert('789'); 46 },false); 47 outer.addEventListener('click',function(){ 48 alert('456'); 49 },false); 50 inner.addEventListener('click',function(){ 51 alert('123'); 52 },false); 53 inner.addEventListener('click',function(){ 54 alert('inner'); 55 },true); 56 wrap.addEventListener('click',function(){ 57 alert('wrap'); 58 },true); 59 outer.addEventListener('click',function(){ 60 alert('outer'); 61 },true); 62 </script> 63 </html>
以上代碼摘自https://segmentfault.com/a/1190000003497939)
點擊查看此案例,我們會發現,首先是觸發的是捕獲階段的事件,然后再觸發的是冒泡階段的事件。
我們會發現inner的dom對象上綁定的兩個事件,是先彈出的123,然后又彈出的inner。這個是為什么呢?
這是因為如果當前的dom對象已經處于當前點擊位置的最底部了(重點是這里最底部,如果沒有到最底部,還是和外部的兩個一樣的)。就是說如果這個dom對象是捕獲的終點也是冒泡的起點,它就不區分冒泡捕獲了,只是純粹的綁定了兩個dom事件,所以,這兩個事件就是看誰先綁定的靠前,誰就先實行。。。
(注:以上內容均來源于網上,基本轉自:http://www.rzrgm.cn/liuwei-0313/p/9935779.html)
浙公網安備 33010602011771號