1. 程式人生 > >事件流機制

事件流機制

只要發生事件,Flash Player 或 AIR 就會排程事件物件。如果事件目標不在顯示列表中,則 Flash Player 或 AIR 將事件物件直接排程到事件目標。例如,Flash Player 將 progress 事件物件直接排程到 URLStream 物件。但是,如果事件目標在顯示列表中,則 Flash Player 將事件物件排程到顯示列表,事件物件將在顯示列表中穿行,直到到達事件目標。

“事件流”說明事件物件如何在顯示列表中穿行。顯示列表以一種可以用樹結構來描述的層次形式進行組織。位於顯示列表層次頂部的是舞臺,它是一個特殊的顯示物件容器,用作顯示列表的根。舞臺由 flash.display.Stage 類表示,且只能通過顯示物件訪問。每個顯示物件都有一個名為 stage

的屬性,該屬性表示應用程式的舞臺。

當 Flash Player 或 AIR 為顯示列表相關的事件排程事件物件時,該事件物件將進行一次從舞臺到“目標節點”的往返行程。DOM 事件規範將目標節點定義為代表事件目標的節點。也就是說,目標節點是發生了事件的顯示列表物件。例如,如果使用者單擊名為 child1 的顯示列表物件,Flash Player 或 AIR 將使用 child1 作為目標節點來排程事件物件。

從概念上來說,事件流分為三部分。第一部分稱為捕獲階段,該階段包括從舞臺到目標節點的父節點範圍內的所有節點。第二部分稱為目標階段,該階段僅包括目標節點。第三部分稱為冒泡階段。冒泡階段包括從目標節點的父節點返回到舞臺的行程中遇到的節點。

如果將顯示列表想像為一個垂直的層次,其中舞臺位於頂層(如下圖顯示),那麼這些階段的名稱就更容易理解了:

如果使用者單擊 Child1 Node,Flash Player 或 AIR 將向事件流排程一個事件物件。如下面的影象所示,物件的行程從舞臺開始,向下移到父節點,然後移到 Child1 節點,再“冒泡”返回到舞臺(即在行程中重新經過父節點,再返回到舞臺)。

在此示例中,捕獲階段在首次向下行程中包括舞臺父節點。目標階段包括在 Child1 花費的時間。冒泡階段包括在向上返回到根節點的行程中遇到的父節點舞臺

事件流使現在的事件處理系統比 ActionScript 程式設計師以前使用的事件處理系統功能更為強大。早期版本的 ActionScript 中沒有事件流,這意味著事件偵聽器只能新增到生成事件的物件。在 ActionScript 3.0 中,您不但可以將事件偵聽器新增到目標節點,還可以將它們新增到事件流中的任何節點。

當用戶介面元件包含多個物件時,沿事件流新增事件偵聽器的功能十分有用。例如,按鈕物件通常包含一個用作按鈕標籤的文字物件。如果無法將偵聽器新增到事件流,您將必須將偵聽器新增到按鈕物件和文字物件,以確保您收到有關在按鈕上任何位置發生的單擊事件的通知。而事件流的存在則使您可以將一個事件偵聽器放在按鈕物件上,以處理文字物件上發生的單擊事件或按鈕物件上未被文字物件遮住的區域上發生的單擊事件。

不過,並非每個事件物件都參與事件流的所有三個階段。某些型別的事件(例如 enterFrame init 型別的事件)會直接排程到目標節點,並不參與捕獲階段和冒泡階段。其他事件可能以不在顯示列表中的物件為目標,例如排程到 Socket 類的例項的事件。這些事件物件也將直接流至目標物件,而不參與捕獲和冒泡階段。

要查明特定事件型別的行為,可以檢視 API 文件或檢查事件物件的屬性。下面的部分介紹瞭如何檢查事件物件的屬性。