November 2006Archives

ExternalInterfaceって匿名関数とかいけるのかなと思って試してみたら案の定いけちゃった。
これって、HTMLや外部JSファイルなどに定義する必要がなくなるって考えられるから素敵。将来のコンテナ拡張はあれだけど・・・。

Flash側でこんなカンジで記述。

import flash.external.*;
var js:String =  "function(){alert('Hello World!');}";
ExternalInterface.call(js);
たしかにアラートが表示されるっ・・・!!
今のところFirefoxとIEで動作確認済み。

すごい昔に同じような手法で、Flash側からコンテナHTMLのテキストを隠すというSEOをやったことがあって、それはJavaScriptのコードもFlashのフレームアクションに文字列として定義してgetURLで実行という手法だったんだけど、ExternalInterfaceでも問題なくいけるのね。

ブラウザの挙動全部見てないからクラスパッケージ化するかは微妙だけど、Firefox2の日本語パス問題の解決に使えそうだなコレ。

日々コードとばかり向かいあっていると、日常的なトークが苦手になるので忘れないようにメモ。
って、コードに関することだけど。

 () カッコ、小カッコ、丸カッコ

 {} 中カッコ、ブレース

 [] 大カッコ、角カッコ、ブラケット

 「」 鍵カッコ

 『』 二重鍵カッコ

もう、間違えませんから。

ActionScriptもJavaScriptも、どっちもECMAScriptに準拠していているから、コアな部分ではほとんど同じだろうと思っていたら、ハマった・・・(MacIE)。

いつもASでやるように、
var a = new Array();
a.push({b:1, c:"22", d:333});
とやったらエラー。
Google先生曰く、「MacIEはArrayクラスでpushをサポートしてねぇ」だそうで。マジすか。どうもWinIE5.0あたりもそうみたい。
結局、pushは使わずにすることでクリア。

で、SWFObjectのソースを読みまくっていたら、こんな記述が(インデントなどはこちらでつけたもの)。
if(Array.prototype.push == null){
	Array.prototype.push = function(_31){
		this[this.length] = _31;
		return this.length;
	};
}
MacIEなどではArrayのpushを自作しているのか!
すごいっ!すごすぎる!!
すかさずprototype.jsはどうなってんだろうと思って調べたら、こっちも同じくサポートしてるっ!

SWFObjectにしてもprototypeにしても、先人は凄いなぁ。
ホント勉強になりまっす!

[ 2006/12/8 追記 ]
prototype.jsのソース見たり、いろいろ検索してみたら、prototype.jsでもサポートしていないっぽいです・・・。prototype.jsってIE6からを対象にしているようですね。
ウェブ人間(きっと)みんな大好きSWFObjectについて、一個だけ注意しなくてはいけないことが。対象バージョンに達しない場合、HTML置換が行われないというヤツ。 たとえば、
var so = new SWFObject("test.swf", "test", "550", "400", "8", "#FFFFFF");
so.write("content");
とすると、Player8以上では表示されるけど、7以下ではHTML置換が起きないので、置換対象タグが空だと何も表示されないという・・・。 これを防ぐためには、上記コンストラクタにリダイレクトURLを引数で渡すことでカスタムエラーページをつくることができるんだけど、他に何か方法ないかとおもって解析してみたら、SWFObjectインスタンスのプロパティで分岐させればいけたっす! SWFObjectのインスタンスは installedVer というObject型のプロパティ持ってて、そこに現在ブラウザにインストールされているFlashPlayerのバージョン情報を格納していると。それをif文かましたサンプルはこんな感じ。
var so = new SWFObject("test.swf", "test", "550", "400", "8", "#FFFFFF");
if(so.installedVer.major >= 8){
	so.write("main");
}else{
	var e = document.getElementById("main");
	e.innerHTML = "(ここにDLページへのリンクなど)";
}
so.installedVerには、major, minor, rev というプロパティがあって、それぞれメジャーバージョン、マイナーバージョン、(revって何の略?)。すべて数値型で文字列じゃないので余裕で比較可能。 うーん、SWFObjectって便利すぎ。ヤバい。作者、頭よすぎだわ。 ExpressInstallを使うなどいろいろあるけど、当分はこれでいこうかな~。
さっきのエントリよりも、こっちの方がFirefox2の致命的な問題。。
Firefox2で再生しているSWFから外部データを読み込もうとすると失敗するってヤツ。あ、主にローカル環境で、サーバーにアップしたら問題ナッシング。

現象を簡単にまとめると、Firefox2でHTMLごしにMovieClipLoaderクラス使って外部SWFの読込をテストしたところ、

(1) ローカル環境など、日本語パスが含まれているデータは読込不可
(2) 日本語パスが含まれていなければ読込可能(Cドライブ直下など)
(3) 同じデータをサーバーにアップすれば問題なし
(4) 上記(1)~(3)をIE6で行うとすべて問題なく読込できる
(5) Firefox1.5ならもちろん問題ない

という結果に。

つまり、Firefox2でHTMLごしにFlashの検証するときは、パスに日本語使うなってことで、それさえしなければOKのよう。

これ、何が致命的に問題かとういうと、「日本語のファイル名を使うな」ではなくて「日本語が含まれるパスで検証はできない」ということ。
SWFが相対パスで読込む外部データが日本語をまったく含まないファイル名だとしても、その上位フォルダに日本語が含まれると一切読み込めなくなる。むむむ・・・。
ということは、"デスクトップ"は日本語でダメなのでデスクトップで検証できないし、ユーザー名に日本語をつけている場合は、データは基本的に "日本語ユーザー名" フォルダの下位に配置されるので MyDocuments フォルダはすべて死ぬことに・・・。
Firefox2ではなくて、IEで検証すればよいだけなんだけど、日ごろFirefoxばっかり使っているからそれはちょっと・・・。

さらに検証を進めてみたんだけど、Firefox2では読込先のファイル名の日本語が化けて認識されるみたい。 相対的なファイルパスをダイナミックテキストフィールドに表示すると化け化け。
詳しいことはわからないけど、たぶんWindowsのファイルシステムの文字コード Shift-JIS と、Flash内部の文字コードUTFまわりが原因なんじゃないかと。
あ、外部データを相対パスではなくて、絶対パスにして行うとFirefox2でも問題なく読込が行われるという!!
var a_mcl = new MovieClipLoader();
a_mcl.loadClip("data.swf"); // 相対パスのため読込エラー
a_mcl.loadClip("file:///C|/Documents and Settings/(ユーザー名)/デスクトップ/data.swf"); // 絶対パスなら読込可能!

なんかパッチみたいなものをASのクラスで作ってみようかな・・・。ExternalInterfaceとか使ってJavaScriptからWindow.locationとか使ってみたらいけそうかも。でも時間ないなー。理ー無ー。

そう言えば豆知識として、この現象は一般にOpera9やFlash8から書き出したプロジェクタ形式でも再現性アリ。IEだけが特殊なんかな・・・。
Firefox2をインストールしたんだけど、しょっちゅう落ちてて。 しかも復帰がダルいっ! タスクマネージャーからアプリを落としても、なんかプロセスとしては生きていて、そのためFirefox2の再起動ができなくなったり。Firefox2を生き返らせるにはプロセスを強引に停止しないといけない・・・。 で、非常にまいってて、いろいろGoogle先生にあれこれ聞いてみたら、mozillaZine 日本語版フォーラム FireFox2で頻繁にフリーズというのが該当して、
ためしにGoogleToolBarをはずしてみたらそれ以来フリーズしてません。 MozillaとGoogleっていつから仲悪くなったのでしょうね。。。
という投稿が! 試しに、GoogleToolbarを無効にしたら無事復活!! う~ん、素敵。 Firefox2に問題があるのかGoogleToolbarに問題があるのかわからんし、他の拡張の設定に影響かもしれないけど、なんとか復活できてよかった・・・。 ちなみにFirefox2のアイコンは少し気に食わないなぁ。前の方がよかった・・・。 もう一個問題あるし。

気がつくと2ヶ月更新を止めているなぁ・・・。
ちょっと、というか、だいぶ落ち着いてきたので再開しまっす。
技術系の小ネタを小出ししていこうと思ったんだけど、おなかすいたからごはん食べて、そのあとたぶん寝て、起きて、会社行って、帰ってきて、また寝て起きて会社行って・・・、たぶん更新しなさそうな気が・・・。
うぅ。

About this archive