ActionScript 3.0 與舊版在事件處理方面的差異

Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本

ActionScript 3.0 與舊版 ActionScript 在事件處理方面,最明顯的差異就是 ActionScript 3.0 中只有一種事件處理系統,而舊版 ActionScript 中卻有數種不同的事件處理系統。本節將以概述舊版 ActionScript 中事件處理的運作方式做為開頭,然後再討論 ActionScript 3.0 中在事件處理方面的變更。

舊版 ActionScript 中的事件處理方式

ActionScript 3.0 之前的 ActionScript 版本是提供多種不同的方式來處理事件:

  • 可以直接置於 Button 和 MovieClip 實體上的 on() 事件處理常式

  • 可以直接置於 MovieClip 實體上的 onClipEvent() 處理常式

  • 回呼函數屬性,例如 XML.onloadCamera.onActivity

  • 使用 addListener() 方法註冊的事件偵聽程式

  • 部分實作 DOM 事件模型的 UIEventDispatcher 類別

上述每一種機制都代表了它自己的各項優點與限制。on()onClipEvent() 處理常式都很容易使用,但是在專案的後續維護方面卻較為困難,因為要找出置於按鈕與影片片段上的程式碼可能會有困難。此外,實作回呼函數也很簡單,但卻會限制您只能針對一個指定的事件來實作一個回呼函數。與之相較,實作事件偵聽程式則較為困難,因為您不僅要建立偵聽程式物件與函數,還必須使用可產生事件的物件來註冊此偵聽程式。不過,這些額外的步驟卻能讓您針對相同的事件,建立多個偵聽程式物件並加以註冊。

ActionScript 2.0 的組件開發工作則產生了另一種事件模型,這個包含在 UIEventDispatcher 類別中的新事件模型是以「DOM 事件規格」的子集為基礎,讓熟悉組件事件處理的開發人員都能輕鬆轉換到新的 ActionScript 3.0 事件模型概念。

可惜的是,不同事件模型使用的語法在多方面都有所重疊,而且各有不同。例如,在 ActionScript 2.0 中,某些屬性 (例如 TextField.onChanged) 可以當做回呼函數或事件偵聽程式來使用。然而,視您使用的是支援偵聽程式的六個類別之一或是 UIEventDispatcher 類別,用來註冊偵聽程式物件的語法會有所不同。若是 Key、Mouse、MovieClipLoader、Selection、Stage 和 TextField 類別,您可以使用 addListener() 方法;但為了組件事件處理作業,則必須使用名為 addEventListener() 的方法。

不同的事件處理模型還會產生另一個複雜的情況,就是事件處理常式函數的範圍會根據所使用的機制大相逕庭。換句話說,在多個事件處理系統中,this 關鍵字的意義並不一致。

ActionScript 3.0 中的事件處理方式

ActionScript 3.0 導入了單一事件處理模型,它取代了舊版程式語言中許多不同的事件處理機制。這個新的事件模型是以「文件物件模型第 3 層事件規格」(Document Object Model (DOM) Level 3 Events Specification) 為基礎。雖然 SWF 檔格式並非特別遵守「文件物件模型」標準,然而在顯示清單與 DOM 結構之間,還是有足夠的相似性,讓實作 DOM 事件模型這件事成為可能。顯示清單中的物件就像是 DOM 階層架構中的節點,而且本段論述中的「顯示清單物件」和「節點」都可以互換使用。

Flash Player 和 AIR 在實作 DOM 事件模型時,加入了名為預設行為的概念。所謂「預設行為」,就是 Flash Player 或 AIR 會當做特定事件之一般結果來執行的動作。

預設行為

通常,開發人員必須負責撰寫可回應事件的程式碼。然而,在某些情況下,某個行為常常會與事件 (除非開發人員新增程式碼來取消該行為,否則 Flash Player 或 AIR 會自動執行該行為) 產生關聯。因為 Flash Player 或 AIR 會自動顯示該行為,所以這種行為便稱為預設行為。

例如,當使用者在 TextField 物件中輸入文字,則通常會期待 TextField 物件中出現該文字,因此這項行為會內建在 Flash Player 或 AIR 中。如果您不要這項預設行為發生,可以使用新的事件處理系統來將其取消。當使用者在 TextField 物件中輸入文字,Flash Player 或 AIR 便會建立 TextEvent 類別的實體,以代表該使用者的輸入動作。若要避免 Flash Player 或 AIR 在 TextField 物件中顯示該文字,您必須存取此特定的 TextEvent 實體,並呼叫此實體的 preventDefault() 方法。

請注意,不是所有的預設行為都能加以避免。例如,當使用者按兩下 TextField 物件中的某個單字時,Flash Player 或 AIR 便會產生 MouseEvent 物件。這項無法避免的預設行為,就是游標下方的單字會呈現反白顯示。

許多類型的事件物件都沒有相關聯的預設行為。例如,當建立網路連線時,Flash Player 便會傳送連線物件,但是並沒有預設行為與它有關聯。Event 類別及其子類別的 API 說明文件會列出每一個事件的類型,並描述任何相關聯的預設行為,以及該行為是否能避免。

您必須知道,預設行為只會與 Flash Player 或 AIR 所傳送的事件物件有關聯,而且透過 ActionScript 以程式設計方式傳送之事件物件的預設行為則不存在。例如,您可以使用 EventDispatcher 類別的方法,傳送類型為 textInput 的事件物件,但是該事件物件將不具有與它相關聯的預設行為。換句話說,Flash Player 和 AIR 將不會在 TextField 物件中顯示字元做為 textInput 事件 (以程式設計的方式傳送) 的結果。

ActionScript 3.0 中事件偵聽程式的新增功能

新的規格對熟悉使用 ActionScript 2.0 addListener() 方法的開發人員而言,將有助於他們瞭解 ActionScript 2.0 事件偵聽程式模型與 ActionScript 3.0 事件模型之間的差異。下表說明這兩個事件模型的幾個主要差異點:

  • 若要在 ActionScript 2.0 中新增事件偵聽程式,那麼在某些情況下您必須使用 addListener(),而其它情況下則必須使用 addEventListener();而在 ActionScript 3.0 中,針對所有的情況您只需使用 addEventListener() 即可。

  • ActionScript 2.0 中沒有事件流程,這表示您只能針對廣播事件的物件呼叫 addListener() 方法;而在 ActionScript 3.0 中,則可以針對屬於事件流程一部分的任何物件呼叫 addEventListener() 方法。

  • 在 ActionScript 2.0 中,事件偵聽程式可以是函數、方法或物件,而在 ActionScript 3.0 中,只有函數或方法可以做為事件偵聽程式。