2009-05-13 17 views
6

画像をプリロードする方法を知りたくはありませんが、ネット上で多くを見つけましたが、その仕組みが分かりたいと思います。 javascriptはどのようにイメージをプリロードできますか? 私は、ここからスニペットを試しましたが、それが動作しても画像をプリロードしていないようです。JavaScriptのプリロードはどのように機能しますか?

ファイヤーバグをチェックすると、画像が2回読み込まれていることがわかります.1回はプリロード中ですが、もう1回表示されます。

このコードを改善するには、どのように動作するのかをご確認ください。ここで

は私が何をすべきかです:

function preload(arrayOfImages) { 
     $(arrayOfImages).each(function(){ 
      $('<img/>')[0].src = this; 
      //(new Image()).src = this; 
      alert(this +' && ' + i++); 

     }); 
    } 

その後、私はそのような何かを実行します。ここでは

preloader = function() { 
    preload(myImages); 
} 

$(document).ready(preloader); 

は私がイメージを追加/表示方法である:

$("li.works").click(function() { 
      $("#viewer").children().empty(); 
      $('#viewer').children().append('<img src=\'images/ref/'+this.firstChild.id+'.jpg\' alt="'+this.firstChild.id+'" \/>') 
      $("#viewer").children().fadeIn(); 
+0

どのように画像を表示しようとしていますか? –

+0

私は私の質問にコードを追加しました。 おそらく、同等の文字列を追加するのではなく、DOMで要素を作成する必要がありますか? –

答えて

11

あなたの基本的なJavascriptプリローダーはこれを行います:

var image = new Image(); 
image.src = '/path/to/the/image.jpg'; 

新しいImageオブジェクトを作成してsrcを設定するだけで、ブラウザはイメージを取得します。 この特定の画像をブラウザに追加するのではありませんが、設定した方法でページに画像が表示されるようになると、ブラウザは既にその画像をキャッシュに保存しています。私は本当になぜあなたが持っているものが、コードを見ることなくこのように動作していないのかをあなたに伝えることはできません。 in this question議論されている

一つの興味深い落とし穴は、あなたが画像の配列を持ち、同じImageオブジェクトを使用して、それらすべてをプリロードしようとすると何が起こるかです:

var images = ['image1.jpg','image2.jpg']; 
var image = new Image(); 
for(var x = 0; x < images.length; x++) { 
    image.src = images[x]; 
} 

これが唯一の残りの部分と最後の画像をプリロードしますオブジェクトのソースを変更するためにループが再び回る前にプリロードする時間がありません。 View an example of this。ボタンをクリックするとすぐに2番目の画像を見ることができるはずですが、最初の画像は表示するときにプリロードする機会を得られないので読み込む必要があります。

そのため、一度に多くを行うための適切な方法は、次のようになります。

var images = ['image1.jpg','image2.jpg']; 
for(var x = 0; x < images.length; x++) { 
    var image = new Image(); 
    image.src = images[x]; 
} 
+1

私のコードはあなたのものと非常に似ていると思います(私はそれを追加するために私の質問を編集しました) Firebugは画像が表示されなければならない毎回画像がロードされていることをまだ私に見せています –

1

それはちょうど新しいDOMのイメージオブジェクトを作成し、src属性を設定することが含まれます。賢明ではなく、AFAIK、それはいつも私のために働いています。

2番目の「ロード」ファンクバグは、キャッシュからロードしていることを示している可能性がありますか?

+0

私はそれをテストして表示しませんキャッシュされたイメージをクリックすると、このページ(http://www.rootspot.com/stackoverflow/preload.php)にロードされます。 –

1

ループのインデックスは、最初の画像で と表示されます。

function preload(arrayOfImages) { 
    $(arrayOfImages).each(function(i){ // Note the argument 
     $('<img/>')[i].src = this; // Note the i 
     //(new Image()).src = this; 
     alert(this +' && ' + i++); 

    }); 
} 

編集:振り返ってみると、これは間違っていたと私はあなたがイメージ要素を作成しようとしている見ることができます インデックスを使用するように変更します。なぜインデックスがあるのか​​分かりません。インデックスは必要ありません。、画像が含まれているDOM要素を作成するときにためた作品をプリロード

$(function() { // Equivalent to $(document).ready() 
    preload(myImages); 
}); 

JavaScriptの画像:私は、関数は次のようになりますと思う:

function preload(arrayOfImages) { 
    $(arrayOfImages).each(function() { 
     $('<img/>').attr('src', this); 
    }); 
}  

そして、それをインスタンス化するために、なぜちょうどこれをしませんイメージがダウンロードされ、キャッシュされます。イメージが実際にHTMLからレンダリングされるときに別の要求が行われたとしても、サーバーは304(変更されていない)を返送し、ブラウザは単にそのキャッシュからイメージをロードします。これは動作しますが

var image = new Image(); 

、これを行うのDOMに準拠した方法は次のとおりです:

パオロは、画像オブジェクトを作成するには、次の表記法を使用してことを示唆するような方法、それはある

var image = document.createElement('img'); 
image.setAttribute('src', 'path/to/image.jpg'); 

このスクリプトではjQueryのHTML文字列リテラル構文を使用している点を除いて、スクリプト内で処理が行われています。さらに、最新のブラウザのほとんどは、DOM標準のメソッドを呼び出すだけで、Image()コンストラクタとの互換性を提供します。

function Image() { 
    return document.createElementNS('http://www.w3.org/1999/xhtml', 'img'); 
} 

Chromeは単なる画像要素を作成するために、ネイティブのDOMメソッドを使用しています:あなたはGoogle ChromeのJavaScriptコンソールを開き、Imageを入力した場合、これはあなたが買ってあげるものです。

+1

新しいImage()ではどのブラウザが停止しますか?また、0からiに変更するという最初の提案は有効ではありません。彼がやっていることは、今作成したDOM要素に直接アクセスしていることです.jQueryはその場合に[0]を保持しています。 –

+0

私はそれに気づかないブラウザは認識していませんが、DOMは言語に依存しないように設計されています。実装によっては、ブラウザが使用するネイティブ実装はDOMでない場合があります。 –

2

"プリロード"という概念では混乱するかもしれません。 <img src="...">でHTMLにたくさんの画像がある場合は、Javascriptでプリロードすることはできません。ページにロードするだけです。

イメージをJavascriptでプリロードすることは、ドキュメントソースにまだ存在しないイメージを読み込んだ後に表示することです。それらは、ページが初めてレンダリングされた後に読み込まれます。それらは、例えばマウスのロールオーバー時に画像を変更する場合など、表示させる際の読み込み時間をなくす/最小限に抑えるためにプリロードされています。

ほとんどのアプリケーションでは、Javascriptの代わりに「CSSスプライト」をプリロードの形式として使用することをお勧めします。 SOにはこれに関する質問がたくさんあるはずです。

+1

+1 - 私はたぶん彼がドキュメントに最初にあったイメージをプリロードしようとしていたとは思わなかった。私は確かにそれが2つの要求を与えることを期待する。 –

5

Javascriptのプリロードは、ブラウザで使用されるキャッシュメカニズムを利用して動作します。

基本的な考え方は、リソースが一度ダウンロードされると、クライアントマシンにローカルに一定期間保存されるため、ブラウザがネットを介してリソースを再度取得する必要がなくなることですブラウザによる表示/使用に必要です。

あなたのコードはおそらくうまく動作しており、Fire Bugが表示しているものを誤って解釈しているだけです。

この理論をテストするには、クリーンなキャッシュを使用してwww.google.comにアクセスしてください。私。まずダウンロード履歴をクリアしてください。

初めてのものは200 OKのステータスを持つ可能性があります。ブラウザーがリソースを要求し、サーバーがそれを送信したことを意味します。 Fire Bugウィンドウの下部を見ると、ページの大きさが195Kbと大きかったことと、どれがキャッシュから取り出されたかが示されます。この場合は0Kbです。

その後、キャッシュをクリアせずに同じページをリロードしても、同じ数のリクエストがFireBugに表示されます。

理由は十分です。ページは変更されておらず、以前と同じリソースが必要です。

これらの要求の大部分は、サーバが304 Not Modified Statusを返したため、ブラウザはキャッシュをチェックしてローカルにリソースが格納されているかどうかを確認しました。この場合、以前のページの読み込み。そこでブラウザはローカルキャッシュからリソースを取り出しただけです。

Fire Bugウィンドウの下部を見ると、ページサイズが同じ(195Kb)で、私の場合は188Kbの大部分がキャッシュからローカルに引き出されていることがわかります。

キャッシュが機能し、Googleが2回目にGoogleにダウンロードして188Kbのダウンロードを保存しました。

イメージをプリロードすると同じことが分かります。要求はまだ行われていますが、サーバが304のステータスを返した場合、イメージは実際にはネットではなくローカルキャッシュから取得されたことになります。

キャッシュでは、将来のすべてのリソース要求を強制終了しないという利点があります。つまり、Uriルックアップは引き続きネットに対して行われますが、可能であればブラウザはローカルキャッシュから引き出して、コンテンツを探すのではなく、ネットの周りを走り回って探しています。

+0

偉大な答え。私はキャッシングがブラウザに全く新しいリクエストを作成できないと思った! –

関連する問題