全画面系Flashの閉じるボタン

いわゆるフローティングレイヤーに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的な書き方で遅延処理を実行するために今回使ってみたのは以下。

便利だ。


新しく会社作りました!

コメントをどうぞ