“Digging more into the EventFlow”的版本间的差异

来自Blueidea
跳转至: 导航搜索
結點
結點
第24行: 第24行:
 
對於顯示對象。當沒有被添加到顯示列表時和非顯示對象派發事件沒有任何區別。而在顯示列表中時才會像這樣。
 
對於顯示對象。當沒有被添加到顯示列表時和非顯示對象派發事件沒有任何區別。而在顯示列表中時才會像這樣。
 
<center>[[Image:FlashPlatform_DisplayObjectNode.png]]</center><br/>
 
<center>[[Image:FlashPlatform_DisplayObjectNode.png]]</center><br/>
 +
根據DOM的定義。並沒有特別對於顯示成員stage的描述。雖然事件流機制被描述為事件首先會經過根節點stage
 +
所以實際上這個圖的情況。也存在完整的事件流階段。一個事件最開始經歷的並不一定是stage
 +
而是從事件派發的目標對象在DOM中的定義,向上遍歷父節點直到根節點。再根據這個DOM的根節點印射出實際對象。
 +
因此以下代碼運行可以發現兩個監聽函數都運行了。
 +
<syntaxhighlight lang="actionscript">
 +
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 ->
 +
}
 +
</syntaxhighlight>
 
為甚麼顯示列表在DOM樹會存在父節點
 
為甚麼顯示列表在DOM樹會存在父節點
 
<center>[[Image:FlashPlatform_DOMSync.png]]</center><br/>
 
<center>[[Image:FlashPlatform_DOMSync.png]]</center><br/>

2011-04-16T23:20:11的版本

深入挖掘ActionScript3事件流的原理和細節。

構架

FlashPlatform DEF base.png

 ActionScript3单一事件处理模型基於W3C DOM3規範。
 簡單來說。AVM2底層將Flash的元素表示一個樹狀結構。複合DOM的規範。
 AVM2的垃圾回收機制也是在此基礎上。參見參考資料中的DOM3核心
 總體上ActionScript3的事件流設施分為以下兩個部份:

FlashPlatform Numbers1.jpg虛線左側的DOM區。這是AVM底層實現並封裝的黑盒,用戶不需要瞭解其中細節。如果您的確要瞭解。請看參考資料。
FlashPlatform Numbers2.jpg虛線右側的Custom區。包含事件流機制構成以及提供給用戶的接口。

DOM區提供一個接入點。用於支持事件流機制以訪問當前對象的樹模型。
用戶不需要知道事件流機制的實現細節也無法修改這個機制,因此只需要提供出派發和接收事件的支持。

結點

事件流機制通常描述為一個三階段的流程。並以stage為根節點出發。

FlashPlatform EFA.jpg

實際上。這個圖解為顯示對象樹。而不是DOM樹。
以下根據良種不同的對象事件傳遞的路徑來區分二者的差異:

對於非顯示對象而言。在DOM中不存在任何的父節點。因此當一個非顯示對象節點派發事件。那麼這個事件會立即回溯

FlashPlatform NormalObjectNode.png

對於顯示對象。當沒有被添加到顯示列表時和非顯示對象派發事件沒有任何區別。而在顯示列表中時才會像這樣。

FlashPlatform DisplayObjectNode.png

根據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樹會存在父節點

FlashPlatform DOMSync.png

FlashPlatform DOMDetail.png

 只有顯示對象樹會同步在DOM區同步一個樹狀關係。這就解釋了為甚麼一個new EventListener()派發出的事件只有這個對象自己可以接收。

同步和異步

在程序的設計上是異步的。具體實現是同步。待編輯條目。

事件流體系結構

參考資料

[DOM3核心]
FlashPlatform GC