当前位置:首页 > 技术 > 正文内容

ActionScript 3与JavaScript双向通信实战指南

访客 技术 2026年8月24日 1

概述

在Web开发中,有时需要实现Flash动画与HTML页面之间的数据交互。本文详细介绍如何在HTML页面中通过JavaScript控制SWF文件的内容,同时让SWF文件能够调用JavaScript函数实现双向通信。

第一步:创建Flash应用程序

使用Flash CC创建一个新的FLA文件,关联一个主类ColorPanel。Flash会自动生成对应的AS3源文件。以下是完整的AS3代码实现:

package  {
    
    import flash.display.MovieClip;
    import flash.text.TextField;
    import flash.events.MouseEvent;
    import flash.external.ExternalInterface;
    import fl.controls.Button;
    import flash.system.System;
    
    public class ColorPanel extends MovieClip {
        
        private var config:Object;
        private var displayText:TextField;
        private var actionButton:Button;
        private var clickCount:int = 0;
        
        public function ColorPanel() {
            //获取外部传入的参数
            config = LoaderInfo(this.root.loaderInfo).parameters;
            
            //初始化交互按钮
            actionButton = new Button();
            actionButton.label = "点击计数";
            actionButton.width = 120;
            actionButton.height = 25;
            actionButton.x = 10;
            actionButton.y = 10;
            this.addChild(actionButton);
            
            //按钮点击事件
            this.actionButton.addEventListener(MouseEvent.CLICK, handleButtonClick);
            
            //初始化文本显示区域
            displayText = new TextField();
            displayText.border = true;
            displayText.borderColor = 0xCCCCCC;
            displayText.x = 10;
            displayText.y = this.actionButton.y + this.actionButton.height + 10;
            displayText.width = this.stage.stageWidth - 20;
            displayText.height = this.stage.stageHeight - this.actionButton.height - 40;
            this.addChild(displayText);

            //读取初始参数
            var initialContent:String = config["content"];
            if (initialContent != null && initialContent.length > 0) {
                displayText.text = initialContent;
            } else {
                displayText.text = "请通过content参数传入初始内容";
            }
            
            //注册JavaScript回调函数
            ExternalInterface.addCallback("updateDisplayText", updateTextContent);
            ExternalInterface.addCallback("getClickCount", retrieveClickCount);
        }
        
        /**
         * 更新文本内容
         */
        private function updateTextContent(newContent:String):void {
            this.displayText.text = newContent;
            //通知JavaScript内容已更新
            if (ExternalInterface.available) {
                ExternalInterface.call("onContentUpdated", "内容更新成功");
            }
        }
        
        /**
         * 获取点击次数
         */
        private function retrieveClickCount():int {
            return this.clickCount;
        }
        
        /**
         * 按钮点击处理
         */
        private function handleButtonClick(event:MouseEvent):void {
            clickCount++;
            var message:String = "当前点击次数: " + clickCount;
            this.displayText.text = message;
            
            //调用外部JavaScript函数
            if (ExternalInterface.available) {
                ExternalInterface.call("onButtonClicked", clickCount);
            }
        }

    }
    
}

完成代码后,在Flash中按Ctrl+Enter生成SWF文件,命名为ColorPanel.swf。

第二步:创建HTML嵌入页面

使用swfobject库将SWF文件嵌入到HTML页面中。swfobject是一个成熟的解决方案,能够自动处理各浏览器的兼容性问题。

<!DOCTYPE html>
<html>
    <head>
        <title>AS3与JavaScript通信演示</title>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <script type="text/javascript" src="swfobject.js"></script>
        <script type="text/javascript">
            var flashId = "flashContainer";
            swfobject.registerObject(flashId, "11.0.0", "expressInstall.swf");
        </script>
        <style>
            body { font-family: Arial, sans-serif; margin: 20px; }
            .control-panel { margin: 10px 0; }
            input { padding: 5px; width: 200px; }
            button { padding: 5px 15px; cursor: pointer; }
        </style>
    </head>
<body>
    <div class="control-panel">
        <input type="text" id="inputField" placeholder="输入要显示的文字" />
        <button onclick="sendToFlash();">发送到SWF</button>
        <button onclick="queryClickCount();">查询点击次数</button>
    </div>
    
    <div>
        <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" 
                width="600" height="400" 
                id="flashContainer">
            <param name="movie" value="ColorPanel.swf">
            <param name="wmode" value="transparent">
            <param name="flashvars" value="content=初始显示内容">
            <!--[if !IE]-->
            <object type="application/x-shockwave-flash" 
                     data="ColorPanel.swf" 
                     width="600" height="400">
                <param name="wmode" value="transparent">
                <param name="flashvars" value="content=初始显示内容">
            <!--[endif]-->
                <a href="http://www.adobe.com/go/getflashplayer">
                    <img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" 
                         alt="获取Adobe Flash播放器">
                </a>
            <!--[if !IE]-->
            </object>
            <!--[endif]-->
        </object>
    </div>

<script language="javascript">
    //获取SWF对象的跨浏览器解决方案
    function getFlashObject() {
        var flashObj = document.getElementById(flashId);
        if (!isIE()) {
            flashObj = document.getElementById(flashId).getElementsByTagName("object")[0];
        }
        return flashObj;
    }
    
    //浏览器检测
    function isIE() {
        return navigator.appName.indexOf("Microsoft") > -1;
    }
    
    //从JavaScript调用AS3函数
    function sendToFlash() {
        var inputValue = document.getElementById("inputField").value;
        var flashObj = getFlashObject();
        if (flashObj && flashObj.updateDisplayText) {
            flashObj.updateDisplayText(inputValue || "未输入内容");
        } else {
            alert("SWF未加载完成,请稍后再试");
        }
    }
    
    //查询AS3中的点击次数
    function queryClickCount() {
        var flashObj = getFlashObject();
        if (flashObj && flashObj.getClickCount) {
            var count = flashObj.getClickCount();
            alert("SWF按钮被点击了 " + count + " 次");
        }
    }
    
    //AS3调用JavaScript的回调函数 - 按钮点击时触发
    function onButtonClicked(count) {
        console.log("SWF按钮被点击,当前次数: " + count);
    }
    
    //AS3调用JavaScript的回调函数 - 内容更新时触发
    function onContentUpdated(message) {
        console.log("SWF内容已更新: " + message);
    }
</script>
</body>
</html>

关键要点分析

1. AS3调用JavaScript函数

在AS3中使用ExternalInterface.call()方法来调用JavaScript函数。第一个参数是JavaScript函数名,后续参数将传递给该JavaScript函数。例如:

//调用JavaScript函数,传递单个参数
ExternalInterface.call("onButtonClicked", clickCount);

//调用JavaScript函数,传递多个参数
ExternalInterface.call("someFunction", "参数1", "参数2", "参数3");

2. JavaScript调用AS3函数

需要在AS3端注册回调函数,使JavaScript能够调用AS3中的方法。关键步骤包括:

  • AS3端注册:使用ExternalInterface.addCallback()方法注册AS3函数,指定JavaScript中调用的别名
  • 获取正确的SWF对象:由于各浏览器获取DOM对象的方式不同,需要编写兼容性代码

浏览器兼容性的处理代码:

function getFlashObject() {
    var flashObj = document.getElementById(flashId);
    //非IE浏览器需要获取嵌套的object元素
    if (!isIE()) {
        flashObj = document.getElementById(flashId).getElementsByTagName("object")[0];
    }
    return flashObj;
}

这是因为在非IE浏览器中,SWF的object元素是嵌套在另一个object元素内部的。

3. 注意事项

  • 确保SWF文件已完全加载后再进行通信
  • 使用ExternalInterface.available检查当前环境是否支持外部接口
  • 通过FlashVars传递初始参数时,使用LoaderInfo(this.root.loaderInfo).parameters读取
  • 如果页面使用了jQuery等库,检测对象是否为空的语法可能有所不同

总结

通过ExternalInterface类,AS3与JavaScript之间可以很方便地进行双向通信。实现过程中需要特别注意浏览器兼容性问题,特别是获取SWF对象的方式。掌握这些要点后,就能在Web项目中灵活实现Flash与HTML的交互功能。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。