天天看點

JavaScript與Flash的通信解析

當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

繼續閱讀