AS3和JS互相调用的小技巧【二】
引用
AS3和JS的互相调用网上一搜能搜到很多,我确实也是这么做的。然而结果却并非令人满意,大部分都是抄子chm帮助手册,或者是叙述得不明白。于是我又手痒了,写篇详细易读的出来,连带分享一个防止缓存的小技巧。
在这里我要先描述一下功能的需求:写死swf文件,读取xml的配置信息,仅靠修改页面上的js代码来改动所需要的xml文件url,并防止缓存。
---
第一步,建立flash as3文件,之后它就不需要改动了,只要编写它的文档类并发布就行。这里我将.fla文件命名为Test.fla,文档类关联为Test.as。
首先我们来展示下AS3中调用JS的方法,这是最简单的事情,简单到只需一句话便可。
AS3的Test.as文档类:
package {
import flash.display.Sprite;
import flash.external.ExternalInterface;
public class Test extends Sprite {
public function Test() {
callJavaScriptFunction();
}
private function callJavaScriptFunction():void {
if(ExternalInterface.available) {
ExternalInterface.call("sayHello", "army");
}
}
}
}
发布页面中的JS代码:
function sayHello(name) {
alert("hello, " + name);
}
as代码很简单,文档类Test继承Sprite,构造函数中执行定义的callJavaScriptFunction()方法。先要说明下ExternalInterface这个类,它在flash.external包下,官方的解释是“在 ActionScript 和 Flash Player 的容器之间实现直接通讯的应用程序编程接口,例如,含有 JavaScript 的 HTML 页。”,可以说是标准的通信接口,只要是和JS互相调用,都要用到它。
在callJavaScriptFunction()方法中,先是判断ExternalInterface.available属性,当外部接口可调用时,执行ExternalInterface类的call方法,它接收若干个参数。第一个是调用的js方法名,后面依次是传给所调用js方法的参数。在这里ExternalInterface.call("sayHello", "army")就相当于执行了js代码中的sayHello("army")方法。如你所见,页面中的确弹出了一个窗口,内容正是传过来的"army"。
需要注意的是,js代码段必须写在嵌入的swf段前面,因为这样才能确保执行之前js全部载入了,否则的话可能会出现无法执行的情况。
---
接下来我们来看看从JS中调用AS的方法。这里我先提个问题:由于放在网络上,swf文件的下载时间是个未知数,如何才能确保js调用as的时候swf已经加载完成了呢?
我所使用的是一个小技巧:依旧是js片段写在swf前面,先在swf里面调用js方法,然后所调用的js方法里再返回去调用as的方法。这样就可以确保swf加载完成并能顺利执行了,整个过程如下:
js片段首先被浏览器读取并加载 =》 浏览器读取swf文件直至完成 =》 swf调用js的方法 =》 被调用的js方法中去调用swf中的as方法。
AS3的Test.as文档类:
package {
import flash.display.Sprite;
import flash.external.ExternalInterface;
import flash.text.TextField;
public class Test extends Sprite {
public function Test() {
callJavaScriptFunction();
}
private function callJavaScriptFunction():void {
if (ExternalInterface.available) {
ExternalInterface.addCallback("callAsFunction", onCallBackHandler);
ExternalInterface.call("callBackBridge");
}
}
private function onCallBackHandler(s:String):void {
var textField:TextField = new TextField();
textField.text = s;
addChild(textField);
}
}
}
发布页面中的JS代码:
function getSwfInstance(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}
function callBackBridge() {
getSwfInstance("Test").callAsFunction("Hello, army!");
}
页面html代码:
<noscript>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="725" height="350" id="VideoCenter" align="center">
<param name="allowScriptAccess" value="sameDomain" /&g