淺談Event Flow、Process、Method及其Applications
事件流動(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.cnblogs.com/liuwei-0313/p/9935779.html)