“Digging more into the EventFlow”的版本间的差异
(→參考資料) |
(→事件流體系結構) |
||
第79行: | 第79行: | ||
==同步和異步== | ==同步和異步== | ||
在程序的設計上是異步的。具體實現是同步。待編輯條目。 | 在程序的設計上是異步的。具體實現是同步。待編輯條目。 | ||
− | |||
− | |||
=== 參考資料 === | === 參考資料 === |
2011-04-16T23:36:38的版本
深入挖掘ActionScript3事件流的原理和細節。
構架
ActionScript3单一事件处理模型基於W3C DOM3規範。 簡單來說。AVM2底層將Flash的元素表示一個樹狀結構。複合DOM的規範。 AVM2的垃圾回收機制也是在此基礎上。參見參考資料中的DOM3核心 總體上ActionScript3的事件流設施分為以下兩個部份:
虛線左側的DOM區。這是AVM底層實現並封裝的黑盒,用戶不需要瞭解其中細節。如果您的確要瞭解。請看參考資料。
虛線右側的Custom區。包含事件流機制構成以及提供給用戶的接口。
DOM區提供一個接入點。用於支持事件流機制以訪問當前對象的樹模型。
用戶不需要知道事件流機制的實現細節也無法修改這個機制,因此只需要提供出派發和接收事件的支持。
結點
事件流機制通常描述為一個三階段的流程。並以stage為根節點出發。
實際上。這個圖解為顯示對象樹。而不是DOM樹。
以下根據良種不同的對象事件傳遞的路徑來區分二者的差異:
對於非顯示對象而言。在DOM中不存在任何的父節點。因此當一個非顯示對象節點派發事件。那麼這個事件會立即回溯
對於顯示對象。當沒有被添加到顯示列表時和非顯示對象派發事件沒有任何區別。而在顯示列表中時才會像這樣。
根據DOM的定義。並沒有特別對於顯示成員stage的描述。雖然事件流機制被描述為事件首先會經過根節點stage 所以實際上這個圖的情況。也存在完整的事件流階段。一個事件最開始經歷的並不一定是stage 而是從事件派發的目標對象在DOM中的定義,向上遍歷父節點直到根節點。再根據這個DOM的根節點印射出實際對象。 因此以下代碼運行可以發現兩個監聽函數都運行了。
package { import flash.display.Sprite; import flash.events.Event; public class RuntimeBindling extends Sprite { //========================================================================== // Constructor //========================================================================== /** Constructor */ public function RuntimeBindling() { const A:Sprite = new Sprite(); const B:Sprite = new Sprite(); A.addChild(B); A.addEventListener("myEvent", A_listener, true); B.addEventListener("myEvent", B_listener); B.dispatchEvent(new Event("myEvent")); } //========================================================================== // Event listeners //========================================================================== private function A_listener(event:Event):void { trace("A_listener"); } private function B_listener(event:Event):void { trace("B_listener"); } } // <- end class -> }
為甚麼顯示列表在DOM樹會存在父節點
所有ActionScript對象會在DOM區建立一個與之對應的定義,不管是顯示對象也好非顯示對象也好並沒有區別。 而只有顯示對象會多一步操作。 在DOM區同步一個樹狀關係。這就解釋了為甚麼一個new EventListener()派發出的事件只有這個對象自己可以接收。
監聽器
與DOM定義不同的是。在ActionScript3中。
監聽一個事件。並不是使用一個實現DOM的EventListener接口的對象實例。當然就不需要實現handleEvent方法。
使用ActionScript的Function監聽就可以了。這的確要比寫一個類要簡單。
如果ActionScript2的玩家新學ActionScript3,突然發現又要addEventListener又要寫EventListener類還要再實現接口。應該會很囧吧。
筆者推測。實際上DOM的handleEvent方法還是實現了的。在事件流機制中。
可以動態的在addEventListener執行時封裝一個實現DOM的EventListener對象並把用戶函數定義在其中
這樣DOM的事件機制傳遞結果給事件流機制的EventListener。再由事件流機制充當中間層將事件經過定義再EventListener中的用戶函數轉發給用戶。
同步和異步
在程序的設計上是異步的。具體實現是同步。待編輯條目。