用FLASH CS3開發,或者在FLEX裡建立AS項目開發,與FLEX裡建立FLEX項目開發,在對於調用外部的問題,比如ExternalInterface類這個命令:結果一樣嗎?答案是不一樣,這是個很奇怪的問題,其實是源於FLEX在建立的時候內部包含的東西很多,還加了個架構,如果你按照FLASH CS3裡開發那樣的命令,去調用外部JS,結果會很糟糕.應該說完全不同.
首先來看一下一個簡單的CASE,先說FLASH CS3裡怎麼做,不過這種方法,我已經在http://www.niuc.net/post/206/裡寫過,很簡單.OK,我按照上面那個qq的例子,做一個改變,就是我在網頁初始後,就希望得到一個我在JS裡寫好的值,並且初始化完成後,在FLASH裡直接顯示.怎麼做?
在網頁代碼裡<object>裡,加一個JS命令,onLoad="所要執行的程式".然後在裡寫那個需要執行的程式,比如
< body onLoad="pageInit()" >
然後在script裡寫上一個初始程式,我是按照以上那個QQ例子來做,那麼就該寫成
function pageInit(){
callAS3(1);
}
那麼得到的結果是,在網頁初始後,FLASH呈現的是穿上編號為1的那個衣服,而不是光著膀子.很簡單,對吧,那麼問題來了,如果按照同樣的方法,在FLEX是否可以實現呢?那麼我們來換一種例子來做,只是簡單的傳輸一個字元.我們首先在FLEX裡寫:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
creationComplete="initApp()">
<mx:Script>
<![CDATA[
import flash.external.*;
public function initApp():void {
ExternalInterface.addCallback("newMessage",newMessage);
}
public function newMessage(s:String):void {
t.text = s;
}
]]>
</mx:Script>
<mx:Text id="t"/>
</mx:Application>
這樣就做好了一個FLEX接受端,可以接受來自外部callApp JS命令,並且把字元在ID為T的text裡顯示.那麼接著寫JS端的(需要在FLEX建立完成後,再在BIN裡修改那個HTML檔案):
<html><head>
<title>Test.html</title>
</head>
<body scroll='no'>
<SCRIPT LANGUAGE="JavaScript">
function callApp() {
getSWF("TestSwf").newMessage(document.getElementById("newTitle").value);
}
function getSWF(movieName){
if (navigator.appName.indexOf("Microsoft") != -1){
return window[movieName]
}
else {
return document[movieName]
}
}
</SCRIPT>
<h1>Test</h1>
<form id="f1">
Enter a new Value: <input type="text" size="30" id="newTitle" >
<input type="button" name="btn" value="SEND" onClick="callApp()">
</form>
<table>
<tr>
<td valign="top">
<object id="TestSwf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" height="200" width="400">
<param name="src" value="test.swf"/>
<embed name="TestSwf" src="test.swf" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" height="200" width="400"/>
</object>
</td>
</tr>
</table>
</body></html>
看這樣就做好了一個很簡單的在網頁傳輸資料,並且在FLEX接收的程式了,那麼我們繼續玩點新花樣,我需要在網頁初始後,FLEX首先能夠顯示出我在網頁裡,或者JS裡預加的值,比如:welcome什麼的.怎麼做?在一開頭,我就用FLASH CS3寫過,直接在object裡放一個onload命令就可以了,但是FLEX能這樣做嗎?答案是否定的,很多人會被這個問題搞暈,那麼到底該如何解決這個問題呢?
其實就是比以前複雜一點,就是多加幾個小確認.由於解釋起來太麻煩,我就把每行代碼都注釋一下,先放FLEX連接埠的Script裡的代碼,其他的都一樣.
<mx:Script>
<![CDATA[
import flash.external.*;
//程式的初始化
public function initApp():void {
//監聽ExternalInterface.available的Boolean值,一般都為TRUE,如果想知道更詳細的情況請參閱協助文檔
if (ExternalInterface.available){
//這個值來自與isContainerReady(),而isContainerReady(),的值是來自ExternalInterface.call("isReady");這個命令,這個命令就是寫在JS裡的,等下我貼JS代碼的時候會放上,如果JS裡的值返回是true,那麼繼續下面的Callback命令.
var containerReady:Boolean = isContainerReady();
if (containerReady) {
Callback();
}
}else{
trace("Wrong Load!")
}
}
private function isContainerReady():Boolean{
var result:Boolean = ExternalInterface.call("isReady");
return result;
}
private function Callback():void {
//這裡就簡單多了,先addCallback好準備要接收的東西,然後call JS裡的命令,以便從JS發送一個值回來,注意次序不要搞錯,錯了就會不成功
ExternalInterface.addCallback("newMessage",newMessage);
ExternalInterface.call("sendMessage");
}
public function newMessage(s:String):void {
t.text = s;
}
]]>
</mx:Script>
下面是JS裡的代碼.同樣也是SCRIPT裡的代碼,不過別忘了object 裡要先寫上onload="pageInit()"這個命令.
<SCRIPT LANGUAGE="JavaScript">
var jsReady = false;
//在預先設定jsReady這個值為false,然後在網頁初始後,讓其值為true;那麼等FLEX在call isReady()這個命令後,會返回一個true值,這樣FLEX裡的程式才會繼續執行.
function pageInit(){
jsReady = true;
}
function isReady(){
return jsReady;
}
//這是等FLEX執行到Callback()後,所發送過來的事件命令,那麼就可以執行這個程式了.執行完成後,就會newMessage 過去到FLEX裡,這樣FLEX裡就會得到一個數值,並把他顯示出來.
function sendMessage(){
getSWF("TestSwf").newMessage("Welcome");
}
function callApp() {
getSWF("TestSwf").newMessage(document.getElementById("newTitle").value);
}
function getSWF(movieName){
if (navigator.appName.indexOf("Microsoft") != -1){
return window[movieName]
}
else {
return document[movieName]
}
}
</SCRIPT>
在FLEX裡要實現網頁初始,並能顯示一個預先設定好的值的確複雜,要是FLASH CS3裡就方便了很多,其他細節還需要自己細細體會了,以下是源檔案,由於安全域問題,可能你把源檔案弄過去後,比較難調試.乾脆直接拷貝代碼到你自己建立的項目就可以了,然後再改HTML的代碼.