monthly gimite

試験運用中。

[js][flash] JavaScriptとFlashを連携させる方法のメモ

web_socket.jsではJavaScriptFlashを連携させる必要があっていろいろ方法を調べたのですが、その結果分かったことをメモしておきます。もっといい方法があるかもしれませんが…。

まず道具としてはswfobjectとFABridgeというのを使うのが便利なようです。それぞれ詳しくはこちら。

swfobjectはJavaScript内でFlashをHTMLに埋め込むライブラリ、FABridgeはFlashのオブジェクトをJavaScriptから操作するライブラリです。

FABridgeはFlex SDKのframeworks/javascript/fabridgeに添付されているので、これをコピーして使います。

JavaScript-Flash間の通信手段としてはFlashに標準でExternalInterfaceというのが用意されているので、単純な通信ならこれでもOKです。が、FABridgeを使うとFlashのオブジェクトをJavaScriptのオブジェクトのように扱えるので、便利です。

罠として、swfobjectで埋め込んだ直後は(まだロードされてないので)Flashにアクセスできません。いろいろ試したのですが、FABridge.addInitializationCallbackというのを使うのがいいようです。使い方はweb_socket.jsのWebSocket.__initializeを見てください。

FABridgeのもう1つの罠として、JavaScriptのfunctionをFlash側に渡すことはできないようです(Stringか何かに化けてしまう)。例外的に、Flashのイベントの仕組みを使った場合は

flashobj.addEventListener("message", function(event){ ... });

という感じでJavaScriptのfunctionを指定できるので、コールバックにはこの方法を使いました。

あと、今回の用途ではFlashそのものは非表示にしつつ実行させる必要がありました。display: noneとかvisibility: hidenとかいろいろ試したのですが、IEだと実行されないとか、いろいろあって、結局position: absolute; top: -100px; left: -100px;とかで表示領域外に追い出すことにしました。

全然関係ないですが…。Flexを使う場合に、Applicationクラスを使うとSWFファイルが180KBぐらい(うろおぼえ)になるのですが、Applicationを使わずにSpriteを継承して実装すると、10KBぐらいになりました。まあ今時大した差ではないのですが。今回はFlashでは何も表示しなかったので、表示する場合にSpriteだけでもちゃんと動くのかは不明。

2010/2/27追記: 罠を1つ追加。ExternalInterface.callまたはFABridgeを使ってFlashからJavaScriptに文字列を渡す場合に、文字列に\(バックスラッシュ)が入っているとエラーになるというバグがあるようです。\をエスケープして\\とするか、escape()したものを渡しておいてJS側でunescape()するなどの対策が必要です。