在Javascript中監聽flash事件,其實有兩種做法:
1、在特定的環境下(例如專門制作的flash),大家約定一個全局函數,然后在flash的事件中用ExternalInterface.call調用這個全局函數即可。
2、在非特定的環境下(例如編寫通用的flash插件),是不能限制用戶的函數名的,所以根本無法約定全局函數;是否可以通過類似js的回調函數的形式實現事件監聽呢?
其實js與flash的通信,一般情況下可以進行一些比較簡單的通信,如傳遞基本的數據類型、傳遞簡單的對象、調用函數等,可是Function(即函數,回調函數肯定都是Function類的實例)不在基本的數據類型中,它是無法被傳遞的。
雖然不知道還有沒其他的方法可以進行傳遞,但至少在我自己的實驗中還沒辦法實現。
所以,如果是第二種情況的話,一般來說比較簡單的方式就是先在flash中實現一個api,通過這個api傳遞某個js的全局函數名稱,然后在flash的事件中調用該函數,如:
在flash中輸入下面的as代碼:
import flash.external.ExternalInterface; var events:Object = {}; // 注冊js可以調用的api ExternalInterface.addCallback("addEventListener", addEventListener); function addEventListener(key:String = null, value:String = null):Boolean { if (key == null || value == null) return false; switch (key) { case "complete": events.complete = value; return true; // 用類似的方式添加其他事件 } return false; }
然后在flash的某個事件中,調用js函數:
import flash.events.Event; import flash.external.ExternalInterface; function complete_handler(event:Event):void { if (events.complete != null) ExternalInterface.call(events.complete); /* 如果需要傳遞參數,請用下面這句: ExternalInterface.call(events.complete, 參數1, 參數2...); */ }
現在,js可以通過下面的代碼監聽時間了:
// swf是你的flash object對象,自行獲取吧 swf.addEventListener("complete", complete_handler); function complete_handler() { alert("事件監聽成功啦~!"); }
可是,上面的監聽方式有個缺點,就是如果事件的參數不是固定的,參數傳遞會很麻煩。或者在有的情況下我還是希望用回調函數的方式來監聽flash事件呢,那么可以在js中做一個事件代理:
var flash = { types: {}, event: function (type) { var listeners = this.types[type]; if (listeners) { for (var i = 0; i < listeners.length; ++i) { listeners[i](); } } }, addEventListener: function (type, fn) { if (!this.types[type]) { this.types[type] = []; } this.types[type].push(fn); } }; flash.addEventListener("load", load); flash.addEventListener("complete", function () { alert("加載完成~!"); }); function load() { alert("正在加載~!"); }
然后在flash事件中調用下面代碼:
import flash.events.Event; import flash.external.ExternalInterface; function load_handler(event:Event):void { ExternalInterface.call("flash.event", "load"); } function complete_handler(event:Event):void { ExternalInterface.call("flash.event", "complete"); }
如果誰還有新的方法或思路,歡迎隨時指教!