以動態方式載入顯示內容

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

您可以將下列任何外部顯示資源載入 ActionScript 3.0 應用程式中:

  • 以 ActionScript 3.0 編寫的 SWF 檔 - 這個檔案可以是 Sprite、MovieClip 或擴充 Sprite 的任何類別。在 iOS 上的 AIR 應用程式r,僅可載入不含 ActionScript 位元碼的 SWF 檔。這表示可載入包含內嵌資料,如影像和聲音的 SWF 檔,但不可載入包含可執行程式碼的 SWF 檔。

  • 影像檔 - 包括 JPG、PNG 和 GIF 檔。

  • AVM1 SWF 檔 - 這是以 ActionScript 1.0 或 2.0 撰寫的 SWF 檔 (行動 AIR 應用程式不支援)。

您可以使用 Loader 類別載入這些資源。

載入顯示物件

Loader 物件是用來將 SWF 檔及圖像檔載入應用程式中。Loader 類別是 DisplayObjectContainer 類別的子類別。Loader 物件只能在其顯示清單中包含一個子顯示物件,顯示物件代表它所載入的 SWF 或圖像檔。當您將 Loader 物件加入顯示清單時 (如下列程式碼所示),也會在載入子顯示物件後,將其加入至顯示清單:

var pictLdr:Loader = new Loader(); 
var pictURL:String = "banana.jpg" 
var pictURLReq:URLRequest = new URLRequest(pictURL); 
pictLdr.load(pictURLReq); 
this.addChild(pictLdr);

載入 SWF 檔或影像以後,您可以將載入的顯示物件移至另一個顯示物件容器,如本範例中的 container DisplayObjectContainer 物件:

import flash.display.*; 
import flash.net.URLRequest; 
import flash.events.Event; 
var container:Sprite = new Sprite(); 
addChild(container); 
var pictLdr:Loader = new Loader(); 
var pictURL:String = "banana.jpg" 
var pictURLReq:URLRequest = new URLRequest(pictURL); 
pictLdr.load(pictURLReq); 
pictLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);  
function imgLoaded(event:Event):void 
{ 
    container.addChild(pictLdr.content);  
}

監視載入進度

檔案開始載入之後,就會建立 LoaderInfo 物件。LoaderInfo 物件會提供資訊,如載入進度、載入器與被載入者的 URL、媒體的位元組總和,以及媒體的表面高度和寬度。LoaderInfo 也會傳送事件,以供監視載入進度。

下圖顯示 LoaderInfo 物件的不同用法,分別針對:SWF 檔之主要類別的實體、Loader 物件,以及由 Loader 物件所載入的物件:

LoaderInfo 物件可以同時做為 Loader 物件和已載入顯示物件的屬性加以存取。載入作業一開始,LoaderInfo 物件就可以透過 Loader 物件的 contentLoaderInfo 屬性加以存取。顯示物件完成載入以後,LoaderInfo 物件也可以做為已載入顯示物件的屬性,透過顯示物件的 loaderInfo 屬性加以存取。已載入顯示物件的 loaderInfo 屬性所參考的 LoaderInfo 物件與 Loader 物件的 contentLoaderInfo 屬性相同;換句話說,已載入的物件與載入該物件的 Loader 物件 (亦即,載入器與被載入者) 會共用一個 LoaderInfo 物件。

若要存取已載入內容的屬性,就要將事件偵聽程式加入至 LoaderInfo 物件,如下列程式碼所示:

import flash.display.Loader; 
import flash.display.Sprite; 
import flash.events.Event; 
 
var ldr:Loader = new Loader(); 
var urlReq:URLRequest = new URLRequest("Circle.swf"); 
ldr.load(urlReq); 
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded); 
addChild(ldr); 
 
function loaded(event:Event):void 
{ 
    var content:Sprite = event.target.content; 
    content.scaleX = 2; 
}

如需詳細資訊,請參閱處理事件

指定載入內容

將外部檔案透過 Loader 類別的 load()loadBytes() 方法載入 Flash Player 或 AIR 之中時,您可以選擇指定 context 參數,這個參數是 LoaderContext 物件。

LoaderContext 類別包括三個屬性,可以讓您定義如何使用載入內容的環境:

  • checkPolicyFile:請只在載入影像檔 (而不是 SWF 檔) 時使用這個屬性。如果將這個屬性設定為 true,Loader 會檢查原則檔的原始伺服器 (請參閱網站控制 (原則檔))。只有在內容不是源自包含 Loader 物件的 SWF 檔時,才需要執行這項步驟。如果伺服器授予 Loader 網域權限,Loader 網域中 SWF 檔的 ActionScript 就可以存取已載入影像中的資料;換句話說,您可以使用 BitmapData.draw() 命令,存取載入影像中的資料。

    請注意,來自 Loader 物件以外網域的 SWF 檔可以呼叫 Security.allowDomain(),以允許特定網域。

  • securityDomain:請只在載入 SWF 檔 (而不是影像) 時使用這個屬性。為不是源自包含 Loader 物件之檔案所屬網域的 SWF 檔指定這個方法。指定這個選項時,Flash Player 會檢查是否有原則檔,如果有,則來自跨網域原則檔中所允許網域的 SWF 檔就可以對載入的 SWF 內容進行跨 Script 處理。您可以將這個參數設定為 flash.system.SecurityDomain.currentDomain

  • applicationDomain:請只在載入以 ActionScript 3.0 撰寫的 SWF 檔 (而非影像或以 ActionScript 1.0 或 2.0 撰寫的 SWF 檔) 時使用此屬性。載入檔案時,您可以透過將 applicationDomain 參數設定為 flash.system.ApplicationDomain.currentDomain,指定檔案要包含在與 Loader 物件相同的應用程式網域中。藉由將載入的 SWF 檔置於相同的應用程式網域中,便可以直接存取其類別。如果您要載入的是包含內嵌媒體 (可以透過它們的相關類別名稱進行存取) 的 SWF 檔,這種做法就很有用。如需詳細資訊,請參閱使用應用程式網域

在下列範例中,會示範從另一個網域載入點陣圖時,檢查原則檔的情形:

var context:LoaderContext = new LoaderContext(); 
context.checkPolicyFile = true; 
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/photo11.jpg"); 
var ldr:Loader = new Loader(); 
ldr.load(urlReq, context);

在下列範例中,會示範從另一個網域載入 SWF 時,檢查原則檔,以便將檔案放入與 Loader 物件相同的安全執行程序中。此外,程式碼也會將已載入 SWF 檔中的類別加入與 Loader 物件相同的應用程式網域中:

var context:LoaderContext = new LoaderContext(); 
context.securityDomain = SecurityDomain.currentDomain; 
context.applicationDomain = ApplicationDomain.currentDomain; 
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/library.swf"); 
var ldr:Loader = new Loader(); 
ldr.load(urlReq, context);

如需詳細資訊,請參閱適用於 Adobe Flash Platform 的 ActionScript 3.0 參考中的 LoaderContext 類別。

在 AIR for iOS 中載入 SWF 檔案

在 iOS 裝置上,於執行階段載入並編譯程式碼時會有一些限制。由於這些限制,將外部 SWF 檔案載入應用程式的工作會有一些必然的差異:

  • 所有包含 ActionScript 程式碼的 SWF 檔案必須包含在應用程式套件中。包含程式碼的 SWF 不得從外部來源 (例如透過網路) 載入。封裝應用程式期間,應用程式套件中所有 SWF 檔案內的所有 ActionScript 程式碼都會編譯為適用於 iOS 裝置的原生程式碼。

  • 您無法載入再取消載入,然後重新載入 SWF 檔案。如果您嘗試執行此操作,就會發生錯誤。

  • 載入再取消載入記憶體的行為,與在桌面平台中相同。如果您載入再取消載入 SWF 檔案,SWF 中的所有視覺資源都會從記憶體中取消載入。然而,載入之 SWF 中 ActionScript 類別的任何類別參照會留在記憶體中,並且可以在 ActionScript 程式碼中存取。

  • 所有載入的 SWF 檔案必須在與主要 SWF 檔案相同的應用程式網域中載入。這不是預設行為,因此,對於所載入的每個 SWF,您必須建立指定主要應用程式網域的 LoaderContext 物件,並且將該 LoaderContext 物件傳遞至 Loader.load() 方法呼叫。如果您嘗試在主要 SWF 應用程式網域以外的應用程式網域中載入 SWF 檔案,就會發生錯誤。即使載入的 SWF 僅包含視覺資源而沒有 ActionScript 程式碼,也是如此。

    下列範例說明用來將 SWF 從應用程式套件載入主要 SWF 應用程式網域的程式碼:

    var loader:Loader = new Loader(); 
    var url:URLRequest = new URLRequest("swfs/SecondarySwf.swf"); 
    var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null); 
    loader.load(url, loaderContext);

僅包含資源而沒有程式碼的 SWF 檔案可以從應用程式套件或透過網路載入。在任一種情況中,SWF 檔案仍然必須載入主要應用程式網域。

對於 AIR 3.6 以前的 AIR 版本,所有程式碼會在編譯過程中,從主要應用程式 SWF 以外的 SWF 中刪除。僅包含視覺資源的 SWF 檔案可以在執行階段隨附於應用程式套件並載入,但不可以有程式碼。如果您嘗試載入包含 ActionScript 程式碼的 SWF,就會發生錯誤。此錯誤會造成「未編譯的 ActionScript」錯誤對話方塊出現在應用程式中。

請參閱

在 iOS 的 AIR 應用程式中封裝並載入多個 SWF

使用 ProLoader 與 ProLoaderInfo 類別

為了協助預先載入執行階段共享元件庫 (RSL),Flash Professional CS5.5 會導入 fl.display.ProLoader 和 fl.display.ProLoaderInfo 類別。這些類別會鏡像 flash.display.Loader 和 flash.display.LoaderInfo 類別,但可提供更一致性的載入經驗。

此外,ProLoader 還可協助您使用 RSL 預先載入的 Text Layout Framework (TLF),載入 SWF 檔。在執行階段中,預先載入其他 SWF 檔或 SWZ 檔的 SWF 檔 (例如 TLF),需要僅供內部使用的 SWF 包裝檔。由 SWF 包裝檔附加之額外圖層的複雜度,會導致不必要的行為。由於檔案均為一般的 SWF 檔,ProLoader 可解決載入這些檔案的複雜度。ProLoader 類別使用的解決方案對使用者而言一目瞭然,且無需特別在 ActionScript 中處理。此外,ProLoader 會載入正確的一般 SWF 內容。

在 Flash Professional CS 5.5 和更新的版本中,您可以更安全地以 ProLoader 類別,取代 Loader 類別的所有用法。接著,將您的應用程式匯出至 Flash Player 10.2 或更新的版本,讓 ProLoader 可存取所需的 ActionScript functionality。若您使用較舊版的 Flash Player (支援 ActionScript 3.0),也可以使用 ProLoader。不過,使用 Flash Player 10.2 或更新的版本可讓您充分利用 ProLoader 的功能。當您在 Flash Professional CS5.5 或更新的版本中使用 TLF 時,永遠使用 ProLoader。除了 Flash Professional 以外,其他環境均無需使用 ProLoader。

重要事項: 對於在 Flash Professional CS5.5 和更新的版本中發佈的 SWF 檔案,您可以一律使用 fl.display.ProLoader 和 fl.display.ProLoaderInfo 類別,不要使用 flash.display.Loader 和 flash.display.LoaderInfo。

ProLoader 類別提到的問題

ProLoader 類別提到的問題,包括無法處理 legacy Loader 類別。這些問題起因於 TLF 元件庫預先載入 RSL。特別是,套用至使用 Loader 物件來載入其他 SWF 檔案的 SWF 檔案。提到的問題如下:

  • 要載入的檔案和已載入的檔案間之指令碼並非預期。ProLoader 類別會自動將要載入的 SWF 檔設定為已載入的 SWF 檔的父系。因此,要載入的 SWF 檔之通訊,會直接進入已載入的 SWF 檔。

  • SWF 應用程式必須主動管理載入程序。如此一來,則需要實作額外事件,例如 addedremovedaddedToStage 以及 removedFromStage。如果您的應用程式使用 Flash Player 10.2 或更新的版本,ProLoader 則無需進行此額外作業。

更新程式碼以使用 ProLoader 而非 Loader

因為 ProLoader 會鏡像 Loader 類別,所以,您可以輕鬆地在程式碼中切換這兩個類別。以下範例說明如何更新現有程式碼,以使用新類別:

import flash.display.Loader; 
import flash.events.Event; 
var l:Loader = new Loader(); 
 
addChild(l); 
l.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete); 
l.load("my.swf"); 
function loadComplete(e:Event) { 
    trace('load complete!'); 
}

此程式碼可以更新為使用 ProLoader,如下所示:

import fl.display.ProLoader; 
import flash.events.Event; 
var l:ProLoader = new ProLoader(); 
 
addChild(l); 
l.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete); 
l.load("my.swf"); 
function loadComplete(e:Event) { 
    trace('load complete!'); 
}