ExternalInterfaceに挑む

Flashのストレージが動かないと書いたが、状況を整理してみる。

まず、テストページは動作する。

ブラウザ save2local.js storage.js
IE
Firefox ×
Opera ×

これらをダウンロードして組み込み、ホスト上で動かすと動作しない。いや、正確には動作したりしなかったり、だ。何がトリガーとなって動作するかがわからない。

一応、最小構成で動作させると動いた。

そもそも、FlashとJavaScript間で直接通信するのはExternalInterfaceというらしく、これが働いていないおかげで、結果としてFlashのストレージが機能していないようだ。

というわけで幾つか策を練ってみた。検証には3ブラウザで動作したsave2localを使用する。Flashのバージョンは全て9.0.16.0だ。

DOMの汚染

真っ先に思いついたのがコレ。特殊なアプリに組み込んでいるから動作しないのではないか?

そこで、最小構成で動作するページを用意し、そのページをIFrameで呼び出し、

document.getElementById( id ).contentWindow.save2local.saveData( key, value );

こなかじに直接引っ張ってみる。

結果:失敗

まさかIFrame内まで汚染するというのか!? と思ったが、さすがにそれはないだろう。だとすると他の原因があるはずだ。しかも、動作したりしなかったりしていたということから見ても、ほんの少しの違いで動作するようなもののはずだ。

JQueryを外す

結果:失敗

とりあえずやってみた。期待はしていなかったが。

ぐぐる

同様にハマってそうな上記2エントリを発見。試しにexternalやらAllowScriptAccessを付けてみた。

結果:失敗

ウボァー

ムネンアトヲタノム

全っっっ然わからん。俺が扱うには経験値が足りなかったということか。つーわけで素直に諦め・・・ようとしたところで動いた。一箇所直しただけで。それを元に戻す。・・・動かなかった。まさか、これで確定?

テストページ

つまり、こういうことか。

Flashがdisplay:noneになっていると、ExternalInterfaceが動作しない・・・っ!

考察

なぜにdisplay:noneだと動作しないかというと、まずCSSが読み込まれて、Flashを入れるdivにdisplay:noneが設定される。

display:noneが設定されている場合、その中の要素がsrcで何がしかのソースを指していたとしても、どうせ見えないんだからとブラウザ側はダウンロードしようとしない。

つまり、ExternalInterfaceしたくてもFlashそのものが読み込まれていなかったんだよ!

動かなかった原因は明らかにこちら側のミスだったわけであり、そしてこの諦念・・・

・・・でも、それだったら、display:noneな中にFlashを指定して、FlashVarsで渡したものが動作する理由がわからん。

それに、後からdisplay:noneにした場合、既にFlashは読み込まれているから動作すると思ったんだが、動作しなかった。なぜに。

とりあえず分かったのは、noneにしなけりゃ動くっぽいことか。

先生、事件です

IEで動いたり動かなかったりしてる。

新しいタブで開く。⇒動く

F5で更新。⇒動かない。

・・・なぜに初回のみ動くのだ。ってInternetExplorerなら問題無かった。Sleipnir 2.5だと初回のみだった。

あと、IEはdisplay:noneとか関係無しに動いた。さらにわけが分からなくなる。

補足

AllowScriptAccessを設定すると、値によって動作する環境が変化する。

always: ActionScript による JavaScript の呼び出しを常に許可します。
sameDomain: SWF と HTML ページのドメインが一致する場合にのみ、ActionScript による JavaScript の呼び出しを許可します。
never: ActionScript による JavaScript の呼び出しを常に許可しません。

Adobe – デベロッパーセンター : Flash Player 8 のセキュリティ機能の変更点

デフォルトはhttp://%E4%B8%8A%E3%81%A7%E3%81%AA%E3%81%84%E3%81%A8%E5%8B%95%E3%81%8B%E3%81%AA%E3%81%84%E3%81%AE%E3%81%A7%E3%80%81%E6%81%90%E3%82%89%E3%81%8FsameDomain%E3%81%A0%E3%81%A8%E6%80%9D%E3%82%8F%E3%82%8C%E3%82%8B%E3%80%82

save2local.swf.addParam("AllowScriptAccess", "always");

このようにalwaysを設定してやると、IE以外はfile://な環境でも動作した。

と思ったら

同じテストファイルをPC変えて動作させたら全ブラウザがローカルで起動しなくなった。Flashのバージョンは同じなんだが・・・

疑問

上記の方法ならばstorage.jsのほうも同じ方法で動くはずだと思ったが、動作せず。

storage.jsはテストページの時点でIEしか動作しなかったので、IE専用かと思ったが、IEもだめだった。当然display:noneは設定していない。なぜ・・・

戦い終わって ~神々の黄昏~

レイアウトが崩れるのを避けるためにdisplay:noneにしていたのが、そもそもの間違いだった。というわけで、width:0、height:0で適当な場所に転がす。んむ、動作した。

ExternalInterfaceの動作条件にはまだ分からない部分があるが、とりあえず使えるようになっただけでも大きな一歩か。だがあまりにも不安定すぎる。なんなんだこれは。