为 HTML 内容定义类似于浏览器的用户界面

Adobe AIR 1.0 和更高版本

JavaScript 提供了多个 API 来控制显示 HTML 内容的窗口。在 AIR 中,可以通过实现自定义 HTMLHost 类覆盖这些 API。

关于扩展 HTMLHost 类

例如,如果您的应用程序在选项卡式界面中呈现多个 HTMLLoader 对象,可能希望根据所加载的 HTML 页,使用其标题来更改选项卡的标签,而不是主窗口的标题。同样,您的代码可通过以下方式响应 window.moveTo() 调用:在父显示对象容器中重新定位 HTMLLoader 对象、移动包含 HTMLLoader 对象的窗口、不执行任何操作或执行完全不相干的操作。

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 实例。可以通过向 HTMLLoader 的 htmlHost 属性分配不同的 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 对象,并将其主机属性设置为上一步中定义的 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() 创建窗口和 HTMLLoader 对象来实现 createWindow() 函数。还可以单独创建一个 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 类并不会实现可在 feature 字符串中指定的所有功能。您的应用程序必须在适当的时候提供滚动条、位置栏、菜单栏、状态栏和工具栏。

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 更改。以下示例跟踪状态值:

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

一个布尔值,它指定窗口最初是 ( 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() opener parent 将引用打开的 HTML 窗口。