為 HTML 內容定義類似瀏覽器的使用者介面

Adobe AIR 1.0 以及更新的版本

JavaScript 提供了數個 API,可以讓您控制顯示 HTML 內容的視窗。在 AIR 中,實作自訂 HTMLHost 類別,就可以覆寫這些 API。

關於擴充 HTMLHost 類別

舉例而言,如果應用程式在索引標籤式介面中呈現多個 HTMLLoader 物件,您可能會希望載入之 HTML 網頁所做的標題變更可以變更索引標籤的標籤,而非變更主要視窗的標題。同樣地,藉由重新調整 HTMLLoader 物件在其父輩顯示物件容器中的位置、移動包含 HTMLLoader 物件的視窗、完全不執行任何動作,或者完整執行其它某些動作,程式碼便可以回應 window.moveTo() 呼叫。

AIR 的 HTMLHost 類別可以控制下列 JavaScript 屬性和方法:

  • window.status

  • window.document.title

  • window.location

  • window.blur()

  • window.close()

  • window.focus()

  • window.moveBy()

  • window.moveTo()

  • window.open()

  • window.resizeBy()

  • window.resizeTo()

當您使用 new HTMLLoader() 建立 HTMLLoader 物件時,並不會啟用上述所列的 JavaScript 屬性或方法。HTMLHost 類別會提供這些 JavaScript API 的預設實作,該實作與瀏覽器類似。您也可以擴充 HTMLHost 類別以自訂行為。若要建立支援預設行為的 HTMLHost 物件,請將 HTMLHost 建構函式中的 defaultBehaviors 參數設定為 true:

var defaultHost:HTMLHost = new HTMLHost(true); 

當您在 AIR 中使用 HTMLLoader 類別 createRootWindow() 方法建立 HTML 視窗時,會自動指定支援預設行為的 HTMLHost 實體。您可以將不同的 HTMLHost 實作指定給 HTMLLoader 的 htmlHost 屬性以變更主控物件行為,或者指定 null 以停用這整個功能。

備註: AIR 會將預設的 HTMLHost 物件指定給針對 HTML 類型之 AIR 應用程式所建立的初始視窗,以及 JavaScript window.open() 方法的預設實作所建立的所有視窗。

範例:擴充 HTMLHost 類別

下列範例會說明如何藉由擴充 HTMLHost 類別,自訂 HTMLLoader 物件影響使用者介面的方式:

Flex 範例:

  1. 建立可擴充 HTMLHost 類別的類別 (子類別)。

  2. 覆寫這個新類別的方法,以處理與使用者介面相關之設定中的變更。例如,下列類別 CustomHost 會針對 window.open() 的呼叫以及 window.document.title 的變更定義行為。對 window.open() 的呼叫會在新視窗中開啟 HTML 網頁,而 window.document.title 的變更 (包含 HTML 網頁的 <title> 元素設定) 會設定該視窗的標題。

    package 
    { 
        import flash.html.*; 
        import flash.display.StageScaleMode; 
        import flash.display.NativeWindow; 
        import flash.display.NativeWindowInitOptions; 
     
        public class CustomHost extends HTMLHost 
        { 
            import flash.html.*; 
            override public function 
                createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader 
            { 
                var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); 
                var bounds:Rectangle = new Rectangle(windowCreateOptions.x, 
                                                windowCreateOptions.y, 
                                                windowCreateOptions.width, 
                                                windowCreateOptions.height); 
                var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, 
                                            windowCreateOptions.scrollBarsVisible, bounds); 
                htmlControl.htmlHost = new HTMLHostImplementation(); 
                if(windowCreateOptions.fullscreen){ 
                    htmlControl.stage.displayState = 
                        StageDisplayState.FULL_SCREEN_INTERACTIVE; 
                } 
                return htmlControl; 
            } 
            override public function updateTitle(title:String):void 
            { 
                htmlLoader.stage.nativeWindow.title = title; 
            } 
        } 
    }
  3. 在包含 HTMLLoader 的程式碼 (而非 HTMLHost 的新子類別之程式碼) 中,建立新類別的物件。指定這個新物件給 HTMLLoader 的 htmlHost 屬性。下列 Flex 程式碼會使用在上一個步驟中定義的類別 CustomHost:

    <?xml version="1.0" encoding="utf-8"?> 
    <mx:WindowedApplication 
        xmlns:mx="http://www.adobe.com/2006/mxml" 
        layout="vertical" 
        applicationComplete="init()"> 
        <mx:Script> 
            <![CDATA[ 
                import flash.html.HTMLLoader; 
                import CustomHost; 
                private function init():void 
                { 
                    var html:HTMLLoader = new HTMLLoader(); 
                    html.width = container.width; 
                    html.height = container.height; 
                    var urlReq:URLRequest = new URLRequest("Test.html"); 
                    html.htmlHost = new CustomHost(); 
                    html.load(urlReq); 
                    container.addChild(html); 
                } 
            ]]> 
        </mx:Script> 
        <mx:UIComponent id="container" width="100%" height="100%"/> 
    </mx:WindowedApplication>

若要測試在此所述的程式碼,請將具有下列內容的 HTML 檔包含在應用程式目錄中:

<html> 
    <head> 
        <title>Test</title> 
    </head> 
    <script> 
        function openWindow() 
        { 
            window.runtime.trace("in"); 
            document.title = "foo" 
            window.open('Test.html'); 
            window.runtime.trace("out"); 
        } 
    </script> 
    <body> 
        <a href="#" onclick="openWindow()">window.open('Test.html')</a> 
    </body> 
</html>

Flash Professional 範例:

  1. 建立供 AIR 使用的 Flash 檔案。將這個檔案的文件類別設定為 CustomHostExample,然後將檔案儲存為 CustomHostExample.fla。

  2. 建立名為 CustomHost.as 的 ActionScript 檔案,其中包含可擴充 HTMLHost 類別的類別 (子類別)。這個類別會覆寫新類別的特定方法,以處理與使用者介面相關之設定中的變更。例如,下列類別 CustomHost 會針對 window.open() 的呼叫以及 window.document.title 的變更定義行為。對 window.open() 方法的呼叫會在新視窗中開啟 HTML 網頁,而 window.document.title 屬性的變更 (包含 HTML 網頁的 <title> 元素設定) 會設定該視窗的標題。

    package 
    { 
        import flash.display.StageScaleMode; 
        import flash.display.NativeWindow; 
        import flash.display.NativeWindowInitOptions; 
        import flash.events.Event; 
        import flash.events.NativeWindowBoundsEvent; 
        import flash.geom.Rectangle; 
        import flash.html.HTMLLoader; 
        import flash.html.HTMLHost; 
        import flash.html.HTMLWindowCreateOptions; 
        import flash.text.TextField; 
     
        public class CustomHost extends HTMLHost 
        { 
            public var statusField:TextField; 
             
            public function CustomHost(defaultBehaviors:Boolean=true) 
            { 
                super(defaultBehaviors); 
            } 
            override public function windowClose():void 
            { 
                htmlLoader.stage.nativeWindow.close(); 
            } 
            override public function createWindow( 
                                    windowCreateOptions:HTMLWindowCreateOptions ):HTMLLoader 
            { 
                var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); 
                var bounds:Rectangle = new Rectangle(windowCreateOptions.x, 
                                                windowCreateOptions.y, 
                                                windowCreateOptions.width, 
                                                windowCreateOptions.height); 
                var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, 
                                            windowCreateOptions.scrollBarsVisible, bounds); 
                htmlControl.htmlHost = new HTMLHostImplementation(); 
                if(windowCreateOptions.fullscreen){ 
                    htmlControl.stage.displayState = 
                        StageDisplayState.FULL_SCREEN_INTERACTIVE; 
                } 
                return htmlControl; 
            } 
            override public function updateLocation(locationURL:String):void 
            { 
                trace(locationURL); 
            } 
            override public function set windowRect(value:Rectangle):void 
            { 
                htmlLoader.stage.nativeWindow.bounds = value; 
            } 
            override public function updateStatus(status:String):void 
            { 
                statusField.text = status; 
                trace(status); 
            } 
            override public function updateTitle(title:String):void 
            { 
                htmlLoader.stage.nativeWindow.title = title + "- Example Application"; 
            } 
            override public function windowBlur():void 
            { 
                htmlLoader.alpha = 0.5; 
            } 
            override public function windowFocus():void 
            { 
                htmlLoader.alpha = 1; 
            } 
        } 
    }
  3. 建立名為 CustomHostExample.as 的 ActionScript 檔案,以包含應用程式的文件類別。這個類別會建立 HTMLLoader 物件,並將其 host 屬性設定為上一個步驟中定義之 CustomHost 類別的實體:

    package 
    { 
        import flash.display.Sprite; 
        import flash.html.HTMLLoader; 
        import flash.net.URLRequest; 
        import flash.text.TextField; 
     
        public class CustomHostExample extends Sprite 
        { 
            function CustomHostExample():void 
            { 
                var html:HTMLLoader = new HTMLLoader(); 
                html.width = 550; 
                html.height = 380; 
                var host:CustomHost = new CustomHost(); 
                html.htmlHost = host; 
                 
                var urlReq:URLRequest = new URLRequest("Test.html"); 
                html.load(urlReq); 
                 
                addChild(html); 
                 
                var statusTxt:TextField = new TextField(); 
                statusTxt.y = 380; 
                statusTxt.height = 20; 
                statusTxt.width = 550; 
                statusTxt.background = true; 
                statusTxt.backgroundColor = 0xEEEEEEEE; 
                addChild(statusTxt); 
                 
                host.statusField = statusTxt; 
            } 
        } 
    }

    若要測試在此所述的程式碼,請將具有下列內容的 HTML 檔包含在應用程式目錄中:

    <html> 
         <head> 
         <title>Test</title> 
         <script> 
         function openWindow() 
         { 
         document.title = "Test" 
         window.open('Test.html'); 
         } 
         </script> 
         </head> 
         <body bgColor="#EEEEEE"> 
         <a href="#" onclick="window.open('Test.html')">window.open('Test.html')</a> 
         <br/><a href="#" onclick="window.document.location='http://www.adobe.com'"> 
         window.document.location = 'http://www.adobe.com'</a> 
         <br/><a href="#" onclick="window.moveBy(6, 12)">moveBy(6, 12)</a> 
         <br/><a href="#" onclick="window.close()">window.close()</a> 
         <br/><a href="#" onclick="window.blur()">window.blur()</a> 
         <br/><a href="#" onclick="window.focus()">window.focus()</a> 
         <br/><a href="#" onclick="window.status = new Date().toString()">window.status=new Date().toString()</a> 
         </body> 
    </html>

處理 window.location 屬性的變更

您可以覆寫 locationChange() 方法,處理 HTML 網頁的 URL 變更。當網頁中的 JavaScript 變更 window.location 的值時,就會呼叫 locationChange() 方法。下列範例只會載入所要求的 URL:

override public function updateLocation(locationURL:String):void 
{ 
    htmlLoader.load(new URLRequest(locationURL)); 
}
備註: 您可以使用 HTMLHost 物件的 htmlLoader 屬性,參考目前的 HTMLLoader 物件。

處理 window.moveBy()、window.moveTo()、window.resizeTo()、window.resizeBy() 的 JavaScript 呼叫

您可以覆寫 set windowRect() 方法,處理 HTML 內容邊界中的變更。當網頁中的 JavaScript 呼叫 window.moveBy() window.moveTo() window.resizeTo() window.resizeBy() 時,就會呼叫 set windowRect() 方法。下列範例只會更新桌面視窗中的邊界:

override public function set windowRect(value:Rectangle):void 
{ 
    htmlLoader.stage.nativeWindow.bounds = value; 
}

處理 window.open() 的 JavaScript 呼叫

您可以覆寫 createWindow() 方法,處理 window.open() 的 JavaScript 呼叫。 createWindow() 方法的實作會負責建立新的 HTMLLoader 物件並將其傳回。您通常可以在新的視窗中顯示 HTMLLoader,但是並不需要建立視窗。

下列範例會示範如何使用 HTMLLoader.createRootWindow() 來實作 createWindow() 函數,以建立視窗和 HTMLLoader 物件兩者。您也可以另外建立 NativeWindow 物件,並將 HTMLLoader 加入至視窗舞台。

override public function createWindow(windowCreateOptions:HTMLWindowCreateOptions):HTMLLoader{ 
    var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); 
    var bounds:Rectangle = new Rectangle(windowCreateOptions.x, windowCreateOptions.y,  
                                windowCreateOptions.width, windowCreateOptions.height); 
    var htmlControl:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, 
                                    windowCreateOptions.scrollBarsVisible, bounds); 
    htmlControl.htmlHost = new HTMLHostImplementation(); 
    if(windowCreateOptions.fullscreen){ 
        htmlControl.stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE; 
    } 
    return htmlControl; 
}
備註: 在這個範例中,會將自訂 HTMLHost 實作指定給使用 window.open() 建立的所有新視窗。如有需要,您也可以使用不同的實作,或者將這些新視窗的 htmlHost 屬性設定為 null。

createWindow() 方法的參數形式傳遞的物件,就是 HTMLWindowCreateOptions 物件。HTMLWindowCreateOptions 類別包含下列屬性,這些屬性會報告在 window.open() 呼叫之 features 參數字串中設定的值:

HTMLWindowCreateOptions 屬性

在 window.open() 之 JavaScript 呼叫的 features 字串中之對應設定:

fullscreen

fullscreen

height

height

locationBarVisible

location

menuBarVisible

menubar

resizeable

resizable

scrollBarsVisible

scrollbars

statusBarVisible

status

toolBarVisible

toolbar

width

width

x

left screenX

y

top screenY

HTMLLoader 類別不會實作可以在 features 字串中指定的所有功能。因此,您的應用程式必須適時提供捲軸、位置列、選單列、狀態列和工具列。

JavaScript window.open() 方法的其它引數都是由系統來處理。 createWindow() 實作不應該在 HTMLLoader 物件中載入內容,或者設定視窗標題。

處理 window.close() 的 JavaScript 呼叫

您可以覆寫 windowClose() 以處理 window.close() 方法的 JavaScript 呼叫。下列範例會在呼叫 window.close() 方法時,關閉桌面視窗:

override public function windowClose():void 
{ 
    htmlLoader.stage.nativeWindow.close(); 
}

window.close() 的 JavaScript 呼叫不一定要關閉包含內容的視窗。例如,您可以從顯示清單移除 HTMLLoader,讓視窗 (可能包含其它內容) 保持為開啟狀態,如下列程式碼所示:

override public function windowClose():void 
{ 
    htmlLoader.parent.removeChild(htmlLoader); 
}

處理 window.status 屬性的變更

您可以覆寫 updateStatus() 方法以處理 window.status 的 JavaScript 變更。下列範例將追蹤 status 值:

override public function updateStatus(status:String):void 
{ 
    trace(status); 
}

要求的狀態會當做字串傳遞至 updateStatus() 方法。

HTMLLoader 物件不會提供狀態列。

處理 window.document.title 屬性的變更

您可以覆寫 updateTitle() 方法以處理 window.document.title 值的 JavaScript 變更。下列範例會變更視窗標題,並且將字串「Sample」附加至標題:

override public function updateTitle(title:String):void 
{ 
    htmlLoader.stage.nativeWindow.title = title + " - Sample"; 
}

設定 HTML 網頁的 document.title 時,所要求的標題就會當做字串傳遞至 updateTitle() 方法。

document.title 的變更不一定要變更包含 HTMLLoader 物件之視窗的標題。舉例而言,您可以變更其它介面元素,例如文字欄位。

處理 window.blur() 和 window.focus() 的 JavaScript 呼叫

您可以覆寫 windowBlur() windowFocus() 方法以處理 window.blur() window.focus() 的 JavaScript 呼叫,如下列範例所示:

override public function windowBlur():void 
{ 
    htmlLoader.alpha = 0.5; 
} 
override public function windowFocus():void 
{ 
    htmlLoader.alpha = 1.0; 
    NativeApplication.nativeApplication.activate(htmlLoader.stage.nativeWindow); 
}
備註: AIR 不會提供用於停用視窗或應用程式的 API。

建立具有捲動 HTML 內容之功能的視窗

HTMLLoader 包含 HTMLLoader.createRootWindow() 靜態方法,可以讓您開啟包含 HTMLLoader 物件的新視窗 (由 NativeWindow 物件表示),並且為該視窗定義某些使用者介面設定。這個方法會採用四個參數,可以讓您定義使用者介面:

參數

說明

visible

Boolean 值,指定一開始就看得見 ( true ) 或看不見 ( false ) 視窗。

windowInitOptions

NativeWindowInitOptions 物件。NativeWindowInitOptions 類別會為 NativeWindow 物件定義數個初始化選項,包括下列項目:視窗是否可以最小化、最大化或重新調整大小;視窗具有系統顏色還是自訂顏色;視窗是否為透明 (針對不使用系統顏色的視窗而言);視窗的類型。

scrollBarsVisible

是 ( true ) 否 ( false ) 具有捲軸。

bounds

定義新視窗之位置和大小的 Rectangle 物件。

例如,下列程式碼會使用 HTMLLoader.createRootWindow() 方法,建立具有會使用捲軸之 HTMLLoader 內容的視窗:

var initOptions:NativeWindowInitOptions = new NativeWindowInitOptions(); 
var bounds:Rectangle = new Rectangle(10, 10, 600, 400); 
var html2:HTMLLoader = HTMLLoader.createRootWindow(true, initOptions, true, bounds); 
var urlReq2:URLRequest = new URLRequest("http://www.example.com"); 
html2.load(urlReq2); 
html2.stage.nativeWindow.activate(); 
備註: 直接在 JavaScript 中呼叫 createRootWindow() 而建立的視窗不會受到開啟的 HTML 視窗影像。舉例來說,JavaScript Window 的 opener parent 等屬性都是 null 。不過,如果您覆寫 HTMLHost createWindow() 方法來呼叫 createRootWindow() ,藉以直接呼叫 createRootWindow() ,則 opener parent 就一定會參考開啟的 HTML 視窗。