いわゆるフローティングレイヤーにFlash載せて、ブラウザ上を動く何かとか作ったりするわけですが、Flash上の閉じるボタンを押した瞬間にFireFoxが音もなく落ちる現象発生。
FlashからはJavaScriptの関数を呼び出して、その関数が当該レイヤーと子であるFlash本体を消していて、とりあえずJS的にはこんなコード。
closeFlash: function() {
Element.hide('test_div');
Element.remove('test_swf');
var so = new SWFObject("/swf/test.swf", "test_swf", "100%", "800px", "8", "#000000");
with (so) {
addParam("wmode", "transparent");
addParam("allowScriptAccess", "always");
write("test_div");
}
}
あ、閉じたあと、またすぐ復旧できるようにFlashのオブジェクトを再作成しています。
Flash側でExternalInterfaceを使ってJSの関数を読んでいるのですが、どうやらその辺がくさい。
ExternalInterfaceは、戻り値を取るので、JS側の処理が終わると、Flashに制御が戻る。
しかしその時点でFlashのオブジェクトはすでに消されているので、行き場所がなくてブラウザが落ちる、ということでしょう。
IEは落ちないんですけどね。プラグインのアクセス方法とメモリの制御に関する違いか。
とりあえず、解決策として戻り値だけ先に返すようにした。
実際にオブジェクトを消去するのは、タイマーで少し遅延させてから。
closeFlash: function() {
this.closeFlash2.callTimeout(200, this);
return true;
},
closeFlash2: function() {
Element.hide('test_div');
Element.remove('test_swf');
var so = new SWFObject("/swf/test.swf", "test_swf", "100%", "800px", "8", "#000000");
with (so) {
addParam("wmode", "transparent");
addParam("allowScriptAccess", "always");
write("test_div");
}
}
prototype的な書き方で遅延処理を実行するために今回使ってみたのは以下。
Kazuho@Cybozu Labs: setTimeout をオブジェクト指向にしてみる
http://labs.cybozu.co.jp/blog/kazuho/archives/2006/12/oo-settimeout.php
便利だ。