AS3和JS互相调用的小技巧【二】

25 篇文章 0 订阅
20 篇文章 0 订阅
[quote]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" />
<param name="allowFullScreen" value="false" />
<param name="movie" value="VideoCenter.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
<embed src="VideoCenter.swf" quality="high" bgcolor="#ffffff" width="725" height="350" name="VideoCenter" align="center" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
</noscript>


为了使大家思路清晰,我们依照上面的过程一步步讲解:

1.js片段首先被浏览器读取并加载
2.浏览器读取swf文件直至完成

这两步没啥好说的,浏览器打开页面就会读取,不关我们的事情。

3.swf调用js的方法

我们看到Test.as中的构造函数依旧调用了callJavaScriptFunction()方法,不过这个方法已有所改变。先是判断ExternalInterface.available属性,然后addCallback()注册一个监听器,再调用js的callBackBridge()方法。
注意监听器必须先注册,这个监听器就是为了js回调as时而注册的,当回调发生时,这个监听器就会被激活,进而执行监听的方法。在这里我们监听js的callAsFunction()方法,并设定回调方法为as的onCallBackHandler()。

4.被调用的js方法中去调用swf中的as方法

由于swf里调用了js的callBackBridge()方法,因此会执行它。callBackBridge()方法内部先是用getSwfInstance()方法取得页面中的swf对象(根据浏览器不同而取得方法不同),然后调用取得对象的callAsFunction()方法,并传递了参数。
由于js中callAsFunction()方法被调用,因此as中注册的监听器监听到了方法名"callAsFunction",并把它转到回调函数onCallBackHandler()上。因此js中执行callAsFunction("Hello, army!")就相当于as中执行了onCallBackHandler("Hello, army!")一样。
结果不出所料,as的onCallBackHandler("Hello, army!")方法被执行,在swf上生成一个文本片段,片段内容正是传递过来的参数"Hello, army!"。

---

结尾的地方我要分享一个防止缓存的小技巧,也就是文章开头所说的功能需求。

通过as调用js方法,再让js回调as方法的这么一个办法,我们可以写死swf文件,通过修改页面中的js代码参数来让swf读取不同的xml配置文件。如果你看懂了上面的说明并亲自动手实践成功了,那么只需做小小修改便能完成这个需求。

接下来的问题是,假如我的xml文件名不想改动,怎么样才能防止缓存呢?

一种办法就是在as的urlloader中读取urlrequest时在xml文件末尾加上随机数,这是自动的办法;另一种就是手动修改js回调函数中的参数,在.xml文件后面加上唯一的随机参数,如:config.xml?1。每更新一次xml文件,就将那个参数+1,如此便能手动防止缓存。

值得一提的是,urlrequest在本地测试时对后面的参数会报错,说找不到文件,放在服务器上它便能够被解析了。
[/quote]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JSJavaScript)和Unity可以通过以下几种方式进行互相调用: 1. 使用Unity的JavaScript API:Unity提供了一套JavaScript API,可以在JS中直接调用Unity的功能。通过Unity的文档和官方教程,我们可以了解到Unity所提供的JavaScript API,然后在JS中使用这些API来调用Unity的功能。 2. 使用Unity的Web Player:Unity有一个Web Player插件,它可以在网页中嵌入Unity应用程序。我们可以在JS中通过JavaScript接口来与嵌入的Unity应用程序进行交互。通过这种方式,我们可以将JS中的数据传递给Unity应用程序,并实现双向通信。 3. 使用Unity的C# API和JS插件:除了使用Unity的JavaScript API,我们还可以使用Unity的C# API来进行互操作。我们可以创建一个C#脚本,实现我们需要的功能,然后在JS中通过调用该脚本来使用Unity的功能。 4. 使用WebSocket通信:WebSocket是一种用于在Web浏览器和Unity应用程序之间进行实时通信的网络协议。我们可以在JS中使用WebSocket API与Unity应用程序建立连接,并通过该连接发送和接收数据。这种方式可以实现实时的数据传输和双向通信。 总结来说,JS和Unity可以通过JavaScript API、Web Player、C# API和JS插件以及WebSocket通信等方式进行互相调用。具体使用哪种方式,取决于我们的需求和技术背景。需要注意的是,在使用这些方式进行互操作时,我们需要充分了解和掌握各种API和技术的使用方法和注意事项,以确保正确地进行调用和交互。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值