[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 phase從Window傳到document對象, 在bubble phase從document對象傳到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的最新標準能夠參見:
http://www.w3.org/TR/html