2008/01/13

Mac版FirefoxのopacityプロパティとFlash

BlogPetを設置してみる。
もちろん、バムセさん。

常に表示されてほしいので、
ウィンドウ(コード上ではsuz.Window)にしたけれど「×」ボタンがないので閉じられない。
ウィンドウ自体は動くけどね。

ところが、かなり大きな問題。
ウィンドウ(しつこいけどsuz.Window)は、
ウィンドウを「表示する」、「閉じる」、「移動する」の操作をすると、
要素のopacityプロパティを変更して、半透明にする。
操作が終了すれば半透明効果も終了するのだけれど、
実はこれにより、BlogPetのFlashが表示されなくなる。
ただし、BlogPetをクリックしたりして、
Flashの再描画をさせるようにすると、更新された部分が表示される。

この現象はMac版Firefoxの場合に発生するバグのようだ。
調べてみると、
 ここ
 ここ
 ここ
にこの現象について解説している箇所がある。
最後のリンク先では「How to Fix This」の項目にて、
Base64エンコードを使えと指摘しているが、
クライアントのパワーだけでBlogPetのFlashをエンコードするのは、酷だろうし、
そもそも、Javascriptで文字列のBase64エンコードはかけられるけど、
バイナリデータはどうやってとってくるんだろう。
Base64エンコードサービスをどこかから借りてくるしかないか。
MacとFirefoxの組み合わせだし、
動作対象にしたいし、僕はまさにこの組み合わせだし......。

まぁまぁ、とりあえず動くので、うちのバムセさんをよろしく。


posted by SuZ at 14:47 | Comment(1) | TrackBack(0) | Programming

2007/06/11

Javascriptの継承

最近の悩み。
ECMAScript言語仕様第3版を読んで、
オライリーのこれも読んで、
Mozillaのここも読んだけれど、
やっぱりまだわからない。
それは、Javascriptオブジェクトの継承。

例えば、prototype.jsを見てみると、
という感じで、
プロパティを単純にコピーしている。
この場合、
Object.extend(A.prototype, B.prototype)とすると、
Java的にはclass A extends Bと言いたくなる。
先を急がず、一方、YUI(Yahoo UI Library)では、
となっている。
prototype.jsと異なっているのは、
superclassのコンストラクタを呼ばずに、
テンポラリなコンストラクタを用意してオブジェクトを生成し、
それをsubclassのprototype属性に入れているところ。
結果としては、subclassのprototypeには、
superclassのプロトタイプ「のみ」が反映されたオブジェクトが、
baseclassのprototypeに代入される。

ところで、
というコンストラクタを定義したとしよう。
このオブジェクトを継承しようとした場合、
prototype.jsのextendもYUIのextendも、
両方ともそれだけでは継承として機能しない。
prototype.jsの場合は、
そもそもprototypeにフィールドやメソッドを定義しておく必要がある。
YUIの場合は、一見するとよさそうだけれども、
実際は空のコンストラクタにより生成されたオブジェクトが利用されるので、
結果としてはfooもbarも継承されない。

では、prototypeにちゃんとフィールドやメソッドを
定義しておけばいいじゃないかという話なのだが、
そうすると、上記Hogeにおけるプライベートフィールドaを
読み取ることが出来なくなってしまう。
(つまり、barからはaが見えなくなってしまう)

そこで、MizillaのJavascript解説でも、
オライリーの例の本でも同様に行なわれいている継承方法が、
である。
確かに、この方法であれば、
Bのコンストラクタが実行されるため、
Hogeで言うところのaを読み取るbarも正常に継承される。

ところが厄介なことに、
(クラス概念を持つオブジェクト指向で言うところの、)
親クラスのコンストラクタを子クラス内で実行した場合、
コンストラクタが2回実行されてしまう。
例えば、
この場合、B.prototype = new A;で一度Aのコンストラクタが、
引数を伴わずに実行され、その結果がB.prototypeに格納される。
この時点で、Bのインスタンスを生成すれば、
自動的にAのもつフィールドやメソッドを継承している。
ところが、Aのコンストラクタは本来引数を伴うべきなので、
Javaのsuper()よろしく、
Bのコンストラクタ内からAのコンストラクタを
thisに新規オブジェクトをバインドさせた状態で呼び出す。
そうすると、Aのコンストラクタの2回目が実行され、
さらに悪いことに、
new B;の結果として生成されたオブジェクトは、
prototype内にAのフィールドとメソッドを持ちながら、
そのオブジェクト自体に、
Aのフィールドやメソッドがアタッチされてしまう。

よって、悩む、悩む。
みなさんはどうやっているのでしょうか?
個人的には、
prototypeには継承元オブジェクトのみを代入して、
コンストラクタでフィールドとメソッドを作ることが、
最も可読性が高く、直感的だと思っているのですが。
(「prototypeに入れたほうがメモリ抑えられるよ」という話は別として)

悩む、悩む。
posted by SuZ at 23:00 | Comment(0) | TrackBack(0) | Programming

2006/10/30

Tracerをこっそりリリース

最近、技術の話が多くなってきたので、
「Google先生に聞いてね」をより積極的に取り入れてみる。

非常に注意深い君なら気付いているかもしれないが、
画面左のメニューに「Tracer」という項目が追加されている。

Tracerとは、一言で言うと、
僕のブログに表示されている文字列を"なぞる"ことで、
その文字列を検索する機能だ。
検索先は
 Googleエンジン
 はてなブログ
 Gooブログ
 Sein und Zeit(本サイト)
の4つ。

検証ブラウザはFirefox1.5.0.7とIE6。
今後はOperaとSafariで検証予定。
(OperaとSafariの方、動作確認にご協力を!)

では、どうぞ。

 Java (←なぞってみよう!)

ぼわっと小さなウィンドウが表示されたかと思う。
タイトルバー上のアイコンで、
ウィンドウをMac風に最小化できたり、
ウィンドウを閉じることができる。
この機能はデフォルトでONになっているので、
うざい人は画面左の"Tracer"メニューからOFFを選択。
以降、文字列をなぞっても検索されなくなる。

著作権はSuZに帰属するけど、
ソースコードの改変/再配布の制限はしないので、ご自由に。
カスタマイズとかした場合には、
(強制ではないですが)参考にしたいので、是非御一報頂ければ。

/**
*TracerはGoogle AJAX Searchを利用して作成されました。
*このようなサービスを無償で提供しているGoogle社に感謝します。
*/
posted by SuZ at 17:48 | Comment(18) | TrackBack(8) | Programming

2006/10/18

JSONPでクロスドメイン

Swing好きの僕としては、
MashUpはSwing派(ちなみにSmashUpと言うらしい)なのだが、
再びJavascriptに手を染めている秋の夜長。

クライアントサイドでのMashUp。
AJAXでMashUpしようにも、
クロスドメイン制限があるため、
サーバサイドでのMashUp結果を頂戴するのが常だった。
これじゃぁ、AJAXがただの「ホワイトアウトしない技術」になってしまう。
(まぁ、実際そうなのかもしれないけれど。)
そこで重くない腰を上げて意気揚々と調べていると、
なにやらたくさん情報がでてくる。
どうやら、思ったよりも浦島なようだ。

JSONPとかいう技術だ。
JSONというのは、
ご存知かどうかは知らないが、
「XMLの変わりにこのフォーマット使ってみない?」なメッセージ形式で、
Javascriptでeval()すると、
Javascriptのオブジェクトが出来上がるという優れもの。
可読性も高いのでいいことばかり。
ちなみにJavaから使う場合に特にいいことはないのが残念。
で、JSONP。
実は、これはAJAXと同じく非同期通信なのだが、
実現方法が全く異なる。

キーは<script>タグ。
実は<script>タグのsrc属性に指定された*.jsファイルは、
ドメインに制限されずにリクエストすることができる。
そして、そのリクエストはブラウザにより非同期に実行される。
さらに、読み込んだ時点で実行時評価される。
勘のいい君ならもうお気付きかもしれないが、
この<script>タグのsrc属性に、
リクエスト先URLを指定して、結果をJSON形式で頂戴する。
その時に、結果をコールバックして欲しい関数名でくくってもらう。
例えば、

 http://hoge.com/search?query=foo&callback=result_func

というURLがJSON形式の結果を返すとしよう。
(queryが検索文字変数、callbackがコールバック変数。)
このURLをsrc属性に指定して動的に<script>タグを作成して、
<head>タグと</head>タグとの間に配置する。
そうすると、ブラウザが勝手にsrcで指定したURLにアクセスする。
結果は次のようなものだとする。

  {"Result":
    [{"Title":"foo",
      "Summary":"bar"
    },
    {"Title":"hoge",
      "Summary":"hmm"
    }]
  }

この結果は正確には以下のように加工されてサーバから返される。

  result_func(
    {"Result":
      [{"Title":"foo",
        "Summary":"bar"
      },
      {"Title":"hoge",
        "Summary":"hmm"
      }]
    }
  );

ブラウザはこれを勝手に実行する。
これが実行されると、
関数result_func(result)が呼ばれることになる。
result_func関数ではeval(result)を実行すれば良い(セキュリティに注意)。
こうして、ドメインを超えて非同期にサーバと通信できるようになる。

理屈が分かればなんてことはない単純なことで、
コードを書くのも数行程度の容易さなのだが、この「思い付き」には感服。
この軽く無茶な感じが、戦国時代としてのWeb2.0に相応しい。
posted by SuZ at 23:02 | Comment(2) | TrackBack(0) | Programming

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。