| 2009.01.24 21:42 |
同じような機能を2つの案件で求められたので作りました。
大きな画像があって、サムネールにロールオーバーすると大きな画像のほうもロールオーバーする、というものです。
for文を回して複数の要素からスコープの異なる他の要素に何かしたいという時、for文内部からaddEventListenerしたりしたい時がありますが、
function hogehoge()
{
var foo = bar.getElementsByTagName("a");
var baz = ["0", "1", "2", "3", "4"];
for(var i=0; i<foo.length; i++)
{
var hoge =baz[i];
var callback = function(){ return hoge; };
foo.addEventListener("mouseover", callback, false);
}
}
こんな風にして、それぞれに何かさせようとしても帰ってくるのはhoge="4"=baz[4]ばかりとなります。イベントが発生する時点ではfor文が回りきった後の変数を見に行くことになるようです。
var callback = (function(_hoge){ return _hoge; })(hoge);
そこで、コールバックに渡す関数を()();で囲います。前の括弧は優先して実行(数式で使う括弧と同じ)、後の括弧は通常通り関数に引数を渡します。こうすると_hogeがゾンビのように生き残り、fooにbaz[i]がわたります。これをクロージャなんて言うらしいです。抽象的に書いたので上のコードは間違ってるかもしれません(汗
同様に
(new Image).src = "path_to_image/hogehoge.jpg";
こうすると、新しいimg要素が作成され、src属性にパスが代入されるとキャッシュに読み込まれます。Firebugを使うと読み込まれているのが確認できます。
青い線はDOMツリー読み込み完了、赤い線はページ読み込み完了です。ページ読み込み完了後に読み込みを開始しているのがJavascriptでの先読み画像です。
Javascriptは自由度が高く、こういう裏技みたいなコードがあって楽しいですね。クロスブラウザはしんどいですが。
