當Flash置於HTML容器中時,經常會遇到AS與JS的通訊問題,例如:JS能否調用AS中的變數、方法,AS能否調用JS中的變數、方法等等。答案是肯定的。隨著技術的不斷髮展,解決方案也是多種多樣的。
在我總結的HTML與FLASH之間的“靜態”傳值一文中提到了JS使用SetVariable方法來設定FLASH中的變數,認為此法已經過時。對此我表示同意,但上文重點畢竟不是在討論JS與AS的通訊,因此另外對AS與JS通訊做一個個人總結,歡迎大家討論。
實現JS跟AS的通訊,目前可選方法比較多,但早期的方法在使用便捷和功能上都不是很完美,下面做一簡要說明:
一、getURL getURL("javascript:history.go(-1)");
通過URL協議來訪問頁面中的javascript,上面控制瀏覽器曆史的代碼很眼熟吧,諸如此類我們平時在定製頁面收藏,發送郵件時都會經常使用這種方式。雖然你也可以調用頁面中自己定義的JS函數,但我個人認為局限性還是比較大,函數的參數傳遞並不是很靈活,無傳回值,而且只能實現AS調用JS,反之不行。
二、fscommand命令
使用fscommand來調用AS定義的方法也是一個很常用的方式,但我們需要在HTML頁面中定義一個具有規定格式的myFlash_DoFSCommand函數,首先定義這個函數我個人就覺得麻煩,而且也只能實現AS調用JS,無函數傳回值。
三、SetVariable
上面兩種方法都只能實現AS調用JS,而SetVariable恰恰相反,只要我們稍微做下處理,他就可以幫我們變相調用AS中的方法。大概思路如下:AS中設定一個狀態變數,並使用Object的watch方法對其監視,JS通過SetVariable來修改這個狀態變數,一旦偵測到了變數的改變,那就可以根據不同的狀態值來選擇執行AS中的相應函數了。如果需要考慮使用者的低版本播放器,那麼你可以考慮下該方法,個人認為還是比較靈活的。
可以看出上面的這些做法都有一定的局限性,所以在我們的應用中很多時候都不得不將他們結合使用。而下面我要具體介紹的就是ExternalInterface的做法,通過它你能輕鬆實現AS與JS的雙向方法調用,從而也解決了雙向的變數訪問,詳細介紹可參見FLASH協助文檔和Adobe的官方教程,下面用兩個簡單例子來說明ExternalInterface的使用。
一、AS調用JS的方法(執行個體示範)
Flash中代碼:
//匯入包
import flash.external.*;
get_btn.onRelease = function(){
//調用頁面中的JS函數
var temp_str = String(ExternalInterface.call("say", "Hello,World"));
result_txt.text = temp_str;
}
Html中代碼:function say(txt){
return txt;
}
沒錯,就這麼簡單,JS函數定義沒有任何要求,AS中使用call方法直接調用就可以了。
二、JS調用AS的方法(執行個體示範)
FLASH中代碼://匯入包
import flash.external.*;
//提供JS訪問的函數名
var _method:String = "say";
//指定本地函數中this變數的範圍,可設定為null留空
var e_area:Object = null;
//AS內建函式名
var method:Function = say;
//將函數註冊到容器列表
var wasSuccessful:Boolean = ExternalInterface.addCallback(_method, e_area, method);
//查看註冊是否成功
if(wasSuccessful){
result_txt.text = "函數註冊成功";
}
//本地的函數
function say(txt:String) {
result_txt.text = txt;
}
Html中代碼:<div>
<form>
<input type="button" onclick="callExternalInterface()" value="JS調用AS方法" />
</form>
<script>
function callExternalInterface() {
thisMovie("demo").say("Hello,World");
}
//瀏覽器安全色訪問DOM
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName]
}
else {
return document[movieName]
}
}
</script>
</div>
其中紅色代碼是核心代碼,其作用原理是AS端通過addCallback函數把AS內部定義的方法註冊為可從容器中調用,允許自訂另外一個方法名供JS來調用這個方法,函數調用成功返回true,失敗返回flase,在此例中通過wasSuccessful變數來判斷函數是否註冊成功。函數註冊成功以後,JS可以通過DOM來訪問SWF對象,然後直接調用預定義的方法即可。
通過比較可以看出,使用ExternalInterface來完成AS和JS的通訊,代碼可以更簡潔,更清晰,功能也更強大,不過還有些細節你需要瞭解,需要使用8.0以上的播放器,對於調用的JS函數不能使用遞迴,同時安全域限制也必須在考慮之中。