[2008.11.19 追記]
関連エントリーとして「ExternalInterfaceでは対象swfをonLoad以降にロードしてはダメ」を投稿しました。
FlashPlayer8からExternalInterfaceを利用することで、かなり簡単にASからJSの関数を呼び出したり、JSからASの関数を呼び出すこともできるようになりました。で、JSからASを呼び出す場合は、あらあじめAS側でJSから呼び出す関数の名前と、実際に実行する関数の登録を行うことで可能になります。たとえばこんな感じ。
ExternalInterface.addCallback('setMessage', this._setMessage);
これだとJS側でswfのオブジェクトを参照してsetMessageを呼び出すと、AS側で_setMessageが呼び出される仕掛けになります。このときにやってみて初めて体験するハマりポイントが多いので、今日はそのポイントのまとめの話。
swfの参照
上記のswfの参照方法はIEとIE以外のブラウザで方法が変わってくるのですが、僕はこんな感じでワンライナーでやってます。
var player = document.all? window[id] : document[id];
上の例のidはobject要素のid属性、embed要素のname属性に設定しておく値です。ポイントはobject要素はidに、embed要素はnameに設定しておくこと。embedでもidに設定すると呼びだしに失敗することもあるので、name属性だけの設定し、id属性には何も設定しないようにすべきです。
また、ここで設定する値は「*external*」な名前にしておかないとIEでコケる場合があります。僕は仕事ではライブ系のswfを扱うケースが多いので「externallive」なんて名前にしがち。(参考情報)
ExternalInterface.addCallbackが確実に完了してから呼び出す
考えてみたら当たり前だけど最近ものすごくハマった点。swfはロードに時間かかる場合があるので、個人的にはJSでwindow.load/DOMContentLoaded時に読み込みをさせる場合が多いのですが、「swfを書き出し」→「swfがExternalInterface.addCallbackを実行」→「JSからASの関数を実行」、としたときにタイミングによってはASの関数呼び出しに失敗します。playerの参照はできても、「setMessage is not function」のようなエラーメッセージが出る場合が多いので、swfはロードできていても、addCallbackの処理が完了していないのが問題です。
こういう場合はASの関数をコールする前に、AS側がaddCallbackの処理が完了したことをJS側に通知 or JSが呼び出したい処理をAS側から呼び出す必要があります。上の例だと、本来はJS側からsetMessageを呼び出すものを、AS側から呼び出します。
ExternalInterface.addCallback('setMessage', this._setMessage);
ExternalInterface.call('setMessage');
この例だとASが呼び出される関数(setMessage)をJS経由で呼び出しているので何か変な感じですが、たとえばsetMessage内でJS側からしか参照できないスコープの変数を利用したいときなどには使えるかと思います。要は、(処理フローとして)addCallbackの完了を確実に保証してあげないと、失敗することが多いですよ、という話。
- Newer: 今更ながらリストレストを購入しました
- Older: Wowza Media Serverの使い方(入門編)
Google Adsense
Social bookmark comment : 0
No comment.
Comment : 0
Trackback : 0
- TrackBack URL for this entry
- http://blog.katsuma.tv/mt-tb.cgi/121
- Listed below are links to weblogs that reference
- ExternalInterfaceでActionScriptの関数呼び出し失敗への対策 from blog.katsuma.tv
2008/02/16 (Sat)