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

Adobe AIR 1.0 和更高版本

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

重要说明: 使用 ActionScript 只能创建 HTMLHost 类的自定义实现。在 HTML 页中,可以导入和使用包含自定义实现的已编译 ActionScript (SWF) 文件。有关将 ActionScript 库导入 HTML 的详细信息,请参阅在 HTML 页中使用 ActionScript 库

关于扩展 HTMLHost 类

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 = 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>
  1. 创建一个 ActionScript 文件,例如 HTMLHostImplementation.as

  2. 在此文件中,定义一个 HTMLHost 类的扩展类。

  3. 覆盖新类的方法以处理用户界面相关设置中的更改。例如,以下 CustomHost 类定义调用 window.open() 和更改 window.document.title 的行为。调用 window.open() 将在新窗口中打开 HTML 页,更改 window.document.title(包括 HTML 页的 <title> 元素的设置)将设置该窗口的标题。

    package { 
        import flash.html.HTMLHost; 
        import flash.html.HTMLLoader; 
        import flash.html.HTMLWindowCreateOptions; 
        import flash.geom.Rectangle; 
        import flash.display.NativeWindowInitOptions; 
        import flash.display.StageDisplayState; 
         
        public class HTMLHostImplementation extends HTMLHost{ 
            public function HTMLHostImplementation(defaultBehaviors:Boolean = true):void{ 
                super(defaultBehaviors);     
            } 
             
            override public function updateTitle(title:String):void{ 
                htmlLoader.stage.nativeWindow.title = title + " - New Host"; 
            } 
             
            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; 
            } 
        } 
    }
  4. 使用 acompc 组件编译器将该类编译为 SWF 文件。

    acompc -source-path . -include-classes HTMLHostImplementation -output Host.zip
    注: acompc 编译器包含在 Flex SDK 中(不是在 AIR SDK 中,AIR SDK 面向通常不需要编译 SWF 文件的 HTML 开发人员。)使用 compc,组件编译器中提供了使用 acompc 的说明
  5. 打开 Host.zip 文件并提取其中的 Library.swf 文件。

  6. Library.swf 重命名为 HTMLHostLibrary.swf。此 SWF 文件是要导入 HTML 页中的库。

  7. 使用 <script> 标签将该库导入 HTML 页:

    <script src="HTMLHostLibrary.swf" type="application/x-shockwave-flash"></script>
  8. 将 HTMLHost 实现的新实例分配到该页的 HTMLLoader 对象。

    window.htmlLoader.htmlHost = new window.runtime.HTMLHostImplementation();

以下 HTML 页说明如何加载和使用 HTMLHost 实现。通过单击按钮打开一个新的全屏窗口,可以测试 updateTitle()createWindow() 实例。

<html> 
    <head> 
    <title>HTMLHost Example</title> 
    <script src="HTMLHostLibrary.swf" type="application/x-shockwave-flash"></script> 
    <script language="javascript"> 
        window.htmlLoader.htmlHost = new window.runtime.HTMLHostImplementation(); 
 
        function test(){ 
            window.open('child.html', 'Child', 'fullscreen'); 
        } 
    </script> 
    </head> 
    <body> 
        <button onClick="test()">Create Window</button> 
    </body> 
</html>

若要运行此示例,请在应用程序目录中提供一个名为 child.html 的 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

leftscreenX

y

topscreenY

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 = new air.NativeWindowInitOptions(); 
var bounds = new air.Rectangle(10, 10, 600, 400); 
var html2 = air.HTMLLoader.createRootWindow(true, initOptions, true, bounds); 
var urlReq2 = new air.URLRequest("http://www.example.com"); 
html2.load(urlReq2); 
html2.stage.nativeWindow.activate();
注: 通过直接在 JavaScript 中调用 createRootWindow() 创建的窗口将独立于打开的 HTML 窗口。例如,JavaScript Window openerparent 的属性为 null。不过,如果通过覆盖 HTMLHost createWindow() 方法间接地调用 createRootWindow()openerparent 将引用打开的 HTML 窗口。