JavaScript 跟 ActionScript 3.0 互動也是通過 flash.external.ExternalInterface 這個類,不過與跟 Flash 8 中跟 ActionScript 2.0 互動所使用的 flash.external.ExternalInterface 還是有所不同的。最大的不同就是 ExternalInterface.addCallback 方法在 ActionScript 3.0 中只有 2 個參數了,而不再有 instance 這個參數。下面要討論的這些問題都是關於 Flash 9 中 ActionScript 3.0 的。
先來說最常遇到的問題,就是在 JavaScript 調用 Flash 中的 ActionScript 方法時報告該方法不存在。這個問題是跟 Flash 中執行 ExternalInterface.addCallback 的時間有關的,ExternalInterface.addCallback 必須要在 HTML 的完全載入之後也就是 window.onload 事件執行後才可以執行,否則,它所發布的方法都無法在 JavaScript 中調用。
解決這個問題的方法在 Flash 9 的 ActionScript 3.0 協助中有個例子,裡麵包含了這個解決方案,就是首先在 js 中設定兩個標誌,例如 jsReady 和 swfReady 這兩個變數作為標誌,開始都設定為 false,當 window.onload 時,設定 jsReady 為 true,在 Flash 中一開始檢查 JavaScript 中的這個 jsReady 標誌是否是 true通過 ExternalInterface.call 方法調用 JavaScript 中的返回這個標誌的一個函數),如果不為 true,就設定一個定時器,經過一段時間後例如 50 或 100 毫秒)重複這個檢查這個標誌,一旦為 true,則執行 ExternalInterface.addCallback 來發布 ActionScript 要提供給 JavaScript 調用的函數或方法,執行完所有的 ExternalInterface.addCallback 後,通過 ExternalInterface.call 方法調用 JavaScript 中的設定 swfReady 標誌的函數設定 swfReady 為 true。之後,當 JavaScript 檢測到 swfReady 為 true 後,再調用 ActionScript 中的方法就不會遇到上的說的這個問題了。
如果簡單一點的調用這樣還可以,如果是有好多這樣的調用就比較麻煩了。我是通過建立兩個執行隊列:jsTaskQueue 和 swfTaskQueue,當在 jsReady 為 true 之前,如果有要調用 ActionScript 的操作,就把這個操作放到 jsTaskQueue 中,當 js 在 window.onload 中執行設定 jsReady 時,把這個隊列中的任務取出來執行,當 jsReady 為 true 後 swfReady 為 true 之前,如果有要調用 ActionScript 的操作,就把這個操作放到 swfTaskQueue 中,當 ActionScript 通過 ExternalInterface.call 方法調用 JavaScript 中的設定 swfReady 標誌的函數設定 swfReady 為 true 時,把這個隊列中的任務取出來執行。當 jsReady 和 swfReady 都為 true 時,那麼如果有要調用 ActionScript 的操作,直接運行就可以了。通過這種方法把這些任務封裝後,使用這些封裝之後的操作,在編寫代碼就可以按照順序而不是非同步)來寫了,執行時也是順序執行啦。
除了這個最常遇到的問題之外,還有兩個關於 IE 上的問題。
如果你是通過 JavaScript 動態建立的 Flash 標籤然後插入到 html 中的話例如通過 innerHTML 賦值的方法或者 appendChild 的方法),很可能你這個操作是在 window.onload 之後才進行,在這種情況下,其它瀏覽器可以正常進行 JavaScript 和 ActionScript 3.0 的互動,IE 就不行。所以,為了保險,最好的方法就是直接把 flash 標籤的 html 寫在 html 的 body 中,或者用 JavaScript 的 document.write 來寫入 html 的 body 中,後面這種方法對於 IE 來說更合適一些,因為這樣的話,可以不需要點擊啟用 Flash。
另一個問題是,不要在 ActionScript 中發布名字為 invoke 的方法,否則在 IE 中,JavaScript 調用該方法時會出錯。
最後一個問題,網上可以查到的比較多了,就是不要把 flash 放到 form 中,否則在 IE 中,JavaScript 調用 ActionScript 時會出錯。當然,網上也給出了一個解決這個問題的指令碼,不過那個貌似是針對 Flash 8 的 ActionScript 2.0 的,我沒有試過,不知道對 ActionScript 3.0 是否同樣有效。
如果在 ActionScript 中通過 ExternalInterface.call 調用 JavaScript 時,如果傳遞的參數有字串,那麼字串中如果包含 \ 符號的話,那麼將會調用失敗。這個也是 ActionScript 和 JavaScript 互動的一個 bug,解決辦法是,對傳遞的字串先進行一下處理在傳遞,處理方法很簡單,比如要傳遞的資料是 data,將它進行一次 data.replace(/\\/, “\\\\”) 替換之後,在傳遞給 JavaScript 就可以了。
- JavaOne 2009第三天:微軟與Sun/Oracle攜手並進
- 開發高可移植性J2ME的軟體
- Java虛擬機器JVM)中的記憶體設定詳解
- 6月程式設計語言熱門排行榜:JavaScript轉正在即
- 不唐突的JavaScript的七條準則