當Flash置于HTML容器中時,經常會遇到AS與JS的通信問題,例如:JS能否調用AS中的變量、方法,AS能否調用JS中的變量、方法等等。答案是肯定的。随着技術的不斷發展,解決方案也是多種多樣的。
在我總結的
[url=http://www.v-sky.com/blog/?p=179][1b]
[color="#80ae14"]HTML與FLASH之間的“靜态”傳值[/color]
[/1b][/url]
一文中提到了JS使用SetVariable方法來設定FLASH中的變量,
[url=http://www.klstudio.com/][1b]
[color="#80ae14"]kinglong[/color]
[/1b][/url]
認為此法已經過時。對此我表示同意,但上文重點畢竟不是在讨論JS與AS的通信,是以另外對AS與JS通信做一個個人總結,歡迎大家讨論。
實作JS跟AS的通信,目前可選方法比較多,但[1b]早期的方法[/1b]在使用便捷和功能上都不是很完美,下面做一簡要說明:
[1b]一、getURL[/1b] getURL("javascript:history.go(-1)");
通過URL協定來通路頁面中的javascript,上面控制浏覽器曆史的代碼很眼熟吧,諸如此類我們平時在定制頁面收藏,發送郵件時都會經常使用這種方式。雖然你也可以調用頁面中自己定義的JS函數,但我個人認為局限性還是比較大,函數的參數傳遞并不是很靈活,無傳回值,而且隻能實作AS調用JS,反之不行。
[1b]二、fscommand指令[/1b]
使用fscommand來調用AS定義的方法也是一個很常用的方式,但我們需要在HTML頁面中定義一個具有規定格式的myFlash_DoFSCommand函數,首先定義這個函數我個人就覺得麻煩,而且也隻能實作AS調用JS,無函數傳回值。
[1b]三、SetVariable[/1b]
上面兩種方法都隻能實作AS調用JS,而SetVariable恰恰相反,隻要我們稍微做下處理,他就可以幫我們變相調用AS中的方法。大概思路如下:AS中設定一個狀态變量,并使用Object的watch方法對其監視,JS通過SetVariable來修改這個狀态變量,一旦偵測到了變量的改變,那就可以根據不同的狀态值來選擇執行AS中的相應函數了。如果需要考慮使用者的低版本播放器,那麼你可以考慮下該方法,個人認為還是比較靈活的。
可以看出上面的這些做法都有一定的局限性,是以在我們的應用中很多時候都不得不将他們結合使用。而下面我要具體介紹的就是[1b]ExternalInterface[/1b]的做法,通過它你能輕松實作[1b]AS與JS的雙向方法調用[/1b],進而也解決了雙向的變量通路,詳細介紹可參見FLASH幫助文檔和
[url=http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=tn_15683]
[color="#80ae14"]Adobe的官方教程[/color]
[/url]
,下面用兩個簡單例子來說明ExternalInterface的使用。
一、AS調用JS的方法([1b]
[url=http://www.v-sky.com/demo/ExternalInterface/astojs/demo.html]
[color="#80ae14"]執行個體示範[/color]
[/url]
[/1b])
Flash中代碼:
//導入包
import flash.external.*;
get_btn.onRelease = function(){
//調用頁面中的JS函數
[color="#ff0000"]var temp_str = String(ExternalInterface.call("say", "Hello,World"));
[/color]
result_txt.text = temp_str;
}
Html中代碼:function say(txt){
return txt;
}
沒錯,就這麼簡單,JS函數定義沒有任何要求,AS中使用call方法直接調用就可以了。
二、JS調用AS的方法([1b]
[url=http://www.v-sky.com/demo/ExternalInterface/jstoas/demo.html]
[color="#80ae14"]執行個體示範[/color]
[/url]
[/1b])
FLASH中代碼://導入包
import flash.external.*;
//提供JS通路的函數名
var _method:String = "say";
//指定本地函數中this變量的作用域,可設定為null留白
var e_area:Object = null;
//AS内部函數名
var method:Function = say;
//将函數注冊到容器清單
[color="#ff0000"]var wasSuccessful:Boolean = ExternalInterface.addCallback(_method, e_area, method);
[/color]
//檢視注冊是否成功
if(
[color="#ff0000"]wasSuccessful[/color]
){
result_txt.text = "函數注冊成功";
}
//本地的函數
function say(txt:String) {
result_txt.text = txt;
}
Html中代碼:
function callExternalInterface() {
[color="#ff0000"]thisMovie("demo").say("Hello,World");
[/color]
}
//浏覽器相容通路DOM
function thisMovie(movieName) {
if (navigator.appName.indexOf("Microsoft") != -1) {
return window[movieName]
}
else {
return document[movieName]
}
}
其中紅色代碼是核心代碼,其作用原理是AS端通過addCallback函數把AS内部定義的方法注冊為可從容器中調用,允許自定義另外一個方法名供JS來調用這個方法,函數調用成功傳回true,失敗傳回flase,在此例中通過wasSuccessful變量來判斷函數是否注冊成功。函數注冊成功以後,JS可以通過DOM來通路SWF對象,然後直接調用預定義的方法即可。
通過比較可以看出,使用ExternalInterface來完成AS和JS的通信,[1b]
[color="#ff0000"]代碼可以更簡潔,更清晰,功能也更強大[/color]
[/1b],不過還有些細節你需要了解,[1b]需要使用8.0以上的播放器,對于調用的JS函數不能使用遞歸,同時安全域限制也必須在考慮之中[/1b]。
本文轉自:http://www.5uflash.com/flashjiaocheng/Flashyuweb/3173.html