[DOM Event Learning] Section 4 事件分發和DOM事件流

聖騎士wind發表於2015-04-01

[DOM Event Learning] Section 4 事件分發和DOM事件流

  
  事件分發機制: event dispatch mechanism.
  事件流(event flow)描述了事件物件在資料結構中是如何傳播的.
 

傳播路徑

  事件物件(event objects)被分發給事件目標(event target),在分發開始的時候,在實現中必須先確定事件物件的傳播路徑.
  這個傳播路徑必須是一個有序的list,其中包含了事件物件必須通過的事件目標.
 
  對於DOM的實現來說,這個傳播路徑必須反映這個文件的分層樹形結構, 路徑list中的最後一個元素必須是該事件的目標元素(event target), 在這之前的所有元素被稱為這個target的祖先(ancestor), 最接近target的一個祖先叫做它的parent
  傳播路徑一旦確定,是不能被更改的. 對於DOM實現來說,即便是傳播路徑中的元素被移動或者刪除, 此條規定也是生效的.
 
  在DOM事件流中, 在事件物件分發的過程中, event listeners可能會改變event target在document中的位置, 這樣的改變不會影響傳播路徑.
  event listener中丟擲的異常不能停止傳播或者影響傳播路徑,異常不能傳播到這個event handler之外.
 

Event phases

 
 
  Capture phase: 事件物件必須從Window一路傳播到target的parent. 也叫capturing phase
  Event listeners registered for this phase must handle the event before it reaches its target.
 
  Target phase: 事件物件必須到達它的target. 也叫at-target phase.
  Event listeners registered for this phase mush handle the event once it has reached its target.
  如果事件型別表明它不能冒泡,在這個階段完成之後事件物件就停止了.
 
  Bubble phase: 冒泡階段. 事件物件從target的parent開始,逆向向祖先傳播,最後到達Window結束. 也叫bubbling phase.
  Event listeners registered for this phase must handle the event after it has reached its target.
 
  Event object必須完成一個或多個phases. 如果一個phase不被支援或者被停止, 則該階段被忽略.
  比如Event.bubbles屬性被置為false,表示不支援這個phase, 則這個phase被忽略.
  Event.stopPropagation()在dispatch之前被呼叫,所有的phases都會被忽略.
 

完成Phase

  實現中, 當有pending event targets在一個phase部分的傳播路徑中, 並且傳播沒有被Event.stopPropagation()停止, 必須讓事件物件按下面的步驟完成一個event phase:
 
  首先, 實現必須確定當前的target.
  這個target必須是傳播路徑中的下一個pending event target,從第一個開始.
  對event listeners來說, 這個target必須是listener在它上面註冊的那個.
 
  然後, 實現必須確定當前target的candidate event listeners.
  這個必須是當前target上所註冊的所有event listener的一個list, 其中各個listener是按照註冊順序排序的.
  一旦確定之後, 這個list是不能被改變的, 增加或者移除listener不會影響當前目標物件的candidate event listeners.
 
  最後,實現中必須按順序處理所有的candidate event handlers, 並且在下列條件都滿足的時候激發每一個handler:
  1. The event object’s immediate propagation has not been stopped.
  2. This listener has been registered for this event phase.
  3. This listener has been registered for this event type.
 
  在產生傳播路徑的時候, event在capture phaseWindow傳到document物件, 在bubble phasedocument物件傳到Window.
 
  在event完成了傳播路徑中的所有phases之後, 它的Event.currentTarget必須被設定為null, Event.eventPhase必須被設定為0 (NONE).
  Event(或繼承Event的其他介面)的所有其他屬性都不變. 包括Event.target屬性, 它必須還是指向event target.
 
  DOM Event flow就是上面這個模型的一個應用.
  所有的事件都完成了capture和target phases, 一個事件是否要完成bubble phase取決於每一個事件的型別.
 
  一些event listener有可能會引起其他事件的分發, 這樣的事件是同步(synchronous)處理的. 也即, 第一個事件傳播只有在新引起的事件分發完成之後才會resume.
 
 
 

參考連結

  本文內容主要來自於其中的3.1 Event dispatch and DOM event flow
 
  該文章的參考資料列表:
 
  W3C的最新標準可以參見:
 

相關文章