Javascript與Flash通訊全解析

原文:https://www.imququ.com/post/39.html html

Flash已經提供了ExternalInterface接口與JavaScript通訊,ExternalInterface有兩個方法,call和addCallback,call的做用是讓Flash調用js裏的方法,addCallback是用來註冊flash函數讓js調用。下面是官方文檔對call和addCallback的說明: 瀏覽器

利用 ActionScript,能夠在 HTML 頁上執行如下操做: 緩存

  • 調用任何 JavaScript 函數。
  • 傳遞任意數量、具備任意名稱的參數。
  • 傳遞各類數據類型(Boolean、Number、String 等等)。
  • 接收來自 JavaScript 函數的返回值。

經過在 HTML 頁上使用 JavaScript,能夠: app

  • 調用 ActionScript 函數。
  • 使用標準的函數調用表示法傳遞參數。
  • 將值返回給 JavaScript 函數。

實際使用的時候,須要注意如下兩點: 函數

1、調用時機。js調用flash對象提供的函數時,可能swf尚未徹底加載完,此時調用會失敗。相似的,flash調用js函數時,也存在js函數還沒load到的狀況。因此adobe官方示例裏採用了一種比較繞的邏輯來避免這種問題: post

  • 頁面上有一個變量_isJSReady,初始爲false。還有一個isJSReady函數用來返回_isJSReady的值,供flash調用。在合適的時機(例如:window.onload),將_isJSReady設置爲true,表示flash可使用js裏的函數了;
  • flash裏有一個定時器,按期(例如:100ms)去調用頁面上的isJSReady方法,直到isJSReady返回true,就能夠addCallback,調用頁面上的flashReadyHandler方法,通知頁面能夠跟flash交互了。

2、如何獲取flash對象。將flash插入到頁面有不少方法,例如swfobject.js或者AC_RunActiveContent.js相似的庫。咱們來看一種最原始的方法,直接在html插入標記來插入flash: spa

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs
/flash/swflash.cab#version=10,0,0,0" width="730" height="520" id="test" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="allowFullScreen" value="false" />
<param name="movie" value="test.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#ffffff" />
    <embed src="test.swf" quality="high" bgcolor="#ffffff"
    width="730" height="520" name="test" align="middle"
    allowScriptAccess="always" allowFullScreen="false"
    type="application/x-shockwave-flash"
    pluginspage="http://www.adobe.com/go/getflashplayer_cn"
     />
</object>

假設test.swf提供了hello的方法,咱們來在js裏調用這個方法,代碼以下: code

document.getElementById("test").hello();

結果,除了IE以外,其餘瀏覽器都不會工做,會提示找不到hello這個方法。這個問題困擾了我比較久。最後發現:在非IE瀏覽器裏,flash提供的方法是加在embed上的,咱們要獲得object下的embed對象,調用embed上的方法纔會成功! htm

官方示例是採用下面方法獲取flash對象的: 對象

function getFlashMovieObject(movieName){
  if (window.document[movieName]){
    return window.document[movieName];
  }else if (navigator.appName.indexOf("Microsoft")==-1){
    if (document.embeds && document.embeds[movieName])
    return document.embeds[movieName];
  }else{
    return document.getElementById(movieName);
  }
}

這裏羅列出全部狀況,固然不會有問題。其實,不必弄得這麼複雜,咱們給object和embed取不一樣名稱,例如一個test1,一個test2,若是是IE就getElementById(「test1」),其它瀏覽器getElementById(「test2」)就好了。另外,若是使用js插入swf的話,極可能js裏就已經作過判斷,根據不一樣瀏覽器來輸出object和embed其中一種。總之,若是調用失敗,首先檢查獲得的flash對象是否是[object HTMLEmbedElement]。

最後,放上一個例子,是我參照官方文檔寫的。

點擊這裏

補充一個細節:在傲遊裏,刷新頁面後js調用flash裏的方法可能會失敗。這篇文章有提到這個問題,解決方法是給swf地址加上隨機數,讓瀏覽器每次都從新加載flash。不過這樣swf就不能被瀏覽器緩存,很無語~下面是一段判斷傲遊的js代碼,建議只針對傲遊加隨機數。

var isMaxthon = false;
try {
    if (external.max_language_id != undefined){
        isMaxthon = true;
    }
}catch (e){}
alert(isMaxthon);
相關文章
相關標籤/搜索