天天看點

[原]as3 flash web 應用 (5)js與flash的互動

2010年06月17日 星期四 19:21

由于某度過于惡心等衆所周知的原因,搬離寫了5年的渣度空間,準備把技術性的文章定在CSDN了。這些都是文章備份。勿怪。。

(鑒于最近有些抓取機器和抄襲者,把标題的【原】字都複制,我不得不聲明:本文為 yukon12345原創,轉載請注明出處http://blog.csdn.net/yukon12345)

[原]as3 flash web 應用 (5)js與flash的互動

完成了UI的操作和上傳功能,接下來就是as3和js的互動。

先普及下知識:

as和js的關系比較有趣,差別于其他互相相似的語言,以形象點方式的說,as和js實質上是同父異母的兄弟關系。

它們的父親就是ECMA(它們都遵循ECMA标準),而“母親”分别是著名的adobe公司和netscape,

由于遵循ECMA标準,基礎核心對象和函數(方法)幾乎是一模一樣。而as和js兩兄弟在網頁前端領域的地位也是數一數二。

雖然actionscript3是走類java的傳統面向對象路線,javascript反而是則是類C的函數式語言(不過也有特殊的原型繼承機制和面向對象方法)。

回歸正題。其實as3和js的互動非常簡單, 關鍵是如何檢測flash影片在網頁中加載完畢,之後兩者才能互動。如果不檢測,将會導緻很多問題。如在flash裡注冊的函數并不能調用,空對象等等

關于互動:使用ExternalInterface類的靜态方法【ExternalInterface.call()】即可調用同一頁面中的js函數使用靜态方法【ExternalInterface.addCalBack()】即可讓js調用as内的方法。

另外還有一個靜态屬性ExternalInterface.available用來檢測容器

例子:

1. ExternalInterface.call(函數名:string,參數1:string|int,參數2...)

特别注意:js能接受的參數1,參數2隻能是string或者int類型,而且它不能自動轉型

比如在AS3中有一個對象A有公共屬性B,那麼如果想A.B做參數的話必須都先String(A.B),來這樣當做參數。

函數名指想調用的js的函數名,參數1,參數2等是傳遞給js函數的參數。

具體實作:在as的某個類中:

ExternalInterface.call("sendToJS", “發給js的字”);

而在js中:function sendToJS(text){alert(text)}

2. ExternalInterface.addCalBack(函數名:string,閉包名)

這裡的函數名指的是js的函數名,指響應哪一個js函數。而閉包指的是一個as3函數的引用。

如 :在js中,

function thisMovie(movieName) {//此為擷取影片
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName];
} else {
return document[movieName];
}
}

function sendToAS(text) {//js發送函數
thisMovie("ExternalInterfaceExample").sendToAS(text);
//“ExternalInterfaceExample”為flash嵌入時候的ID
}
sendToAS("這裡是從js發出的參數")
           

在flash中:

ExternalInterface.addCallback("sendToAS", receivedFromJS)

function receivedFromJS(text){
trace("js:"+text)
}
           

别急着測試,關鍵在于如何檢測flash影片加載完畢。官方的方法是在js中設定一個布爾變量,比如

js:

var jsReady = false;
function isReady() {//傳回此标量。供flash調用。
return jsReady;
}
           

然後在body标簽的onload事件中寫入加載完成時執行處理函數

<body οnlοad="pageInit();">
function pageInit() {
jsReady = true;
}
           

而在flash中,設定一個定時器,定時取jsReady變量值。

as3:

var readyTimer:Timer = new Timer(100, 0);
readyTimer.addEventListener(TimerEvent.TIMER, timerHandler);
readyTimer.start();

function timerHandler(event:TimerEvent):void {
trace("檢查是否準備完畢。。")
var isReady:Boolean = checkJavaScriptReady();
if (isReady) {
output.appendText("JavaScript is ready.\n");
Timer(event.target).stop();
}
}

function checkJavaScriptReady():Boolean {
var isReady:Boolean = ExternalInterface.call("isReady");
return isReady;
}
           

詳細的程式實作可以到 官方的ActionScript3·0語言群組件參考 裡 查找“javascript”

是不是很麻煩?正确加載flash遠遠不止如此,是件非常繁瑣而精細的事情。是以講完原理後,下面就要講如何正确加載