画像の先読み
実現のためのコードはいたってシンプルです。以下のようにします。
var imgObj = new Image(); imgObj.src = "sample1.jpg";
JavaScriptでImageオブジェクトのsrcプロパティに画像アドレスを設定すると、その時点でブラウザが画像をダウンロードするのを利用しています。
以下は引数に画像アドレス配列を渡すと、一括して先読みしてくれる関数です。
function preload(imgs){ for(var i = 0; i < imgs.length; i++){ var imgObj = new Image(); imgObj.src = imgs[i]; } } preload(["sample1.jpg", "sample2.jpg", "sample3.jpg"]);
・・・が、これだけでは先読みの終了どころか、本当に先読みしてるのかもわかりません^^;
テストのために、先読みの経過を表示するコードを追加してみます。
<html> <head> <script type="text/javascript"> function preload(imgs){ var objArray = []; for(var i = 0; i < imgs.length; i++){ var imgObj = new Image(); imgObj.src = imgs[i]; objArray.push(imgObj); } var viewStatus = function(){ var count = 0; var str = ""; for(var i = 0; i < objArray.length; i++){ if(objArray[i].complete) count++; } str += objArray.length + "件中" + count + "件完了"; if(count == objArray.length){ str += ":すべて完了しました。" } var viewElem = document.getElementById("view"); if(viewElem) viewElem.innerHTML = str; if(count < objArray.length){ setTimeout(viewStatus, 100); } }; viewStatus(); } function test(){ preload(["http://f.hatena.ne.jp/images/fotolife/s/susie-t/20070407/20070407220053.jpg", "http://f.hatena.ne.jp/images/fotolife/s/susie-t/20070407/20070407215356.jpg", "http://f.hatena.ne.jp/images/fotolife/s/susie-t/20070407/20070407215255.jpg"]); } </script> </head> <body> <div id="view"></div> <button onclick="test();">preload</button> </body> </html>
preloadボタンを押すと先読みを開始します。で、状態を表示するのですが。。。これぐらいだとすぐに終わってしまいますね^^;大量の画像や重い画像を指定するとよく分かるのですが。手っ取り早く、存在しないアドレスを入れれば途中で止まりますが、ずっとsetTimeoutで回り続けますのでご注意を。また、キャッシュがあるとすぐに終わりますので、再度テストする場合はキャッシュを削除してください。
Imageオブジェクトのcompleteプロパティにより、画像読み込みが完了(=true)したかがわかります。これを利用しています。Imageオブジェクトのonloadイベントを使う手もありますが、ここでは省略させていただきます。(実際には、負荷の面から、1秒ごとにチェックするくらいが妥当な気がしてます。上記コードはテスト用なので0.1秒に設定しています。)