この質問はどこでも、on SOとoffの両方で尋ねられ、答えられたことを完全に承知しています。しかし、毎回異なる答えがあるようです。たとえば、 this =、 this および that 。
JQueryを使用しているかどうかは気にしません。重要なのは、それが機能し、クロスブラウザであることです。]
それでは、画像をプリロードする最良の方法は何ですか?
残念ながら、それはあなたの目的に依存します。スタイルの目的で画像を使用する場合、最善の策はスプライトを使用することです。 http://www.alistapart.com/articles/sprites2
ただし、<img>タグで画像を使用する予定の場合は、次のように事前にロードすることをお勧めします。
_function preload(sources)
{
var images = [];
for (i = 0, length = sources.length; i < length; ++i) {
images[i] = new Image();
images[i].src = sources[i];
}
}
_
( JavaScriptで複数の画像をプリロードする最良の方法は何ですか? )から取得した変更されたソース
new Image()
を使用すると、DOMメソッドを使用する費用はかかりませんが、指定されたイメージの新しいリクエストがキューに追加されます。この時点で画像は実際にはページに追加されていないため、再レンダリングは行われません。ただし、ページの最後にこれを追加して(可能な場合はすべてのスクリプトがそうであるように)、より重要な要素を保持しないようにすることをお勧めします。
編集:コメントを反映するように編集され、適切に機能するには別個のImage
オブジェクトが必要であることを非常に正確に指摘しています。ありがとう.
Edit2:再利用性をより明確にするために編集
Edit 3(3年後):
ブラウザが非表示画像を処理する方法が変更されたため(display:none、またはこの回答のようにドキュメントに追加されない)、プリロードへの新しいアプローチが推奨されます。
Ajaxリクエストを使用して、画像の早期取得を強制できます。たとえば、jQueryを使用します。
_jQuery.get(source);
_
または、前の例のコンテキストでは、次のことができます。
_function preload(sources)
{
jQuery.each(sources, function(i,source) { jQuery.get(source); });
}
_
これはそのままのスプライトの場合には適用されないことに注意してください。これは、写真ギャラリーやスライダー/カルーセルなど、画像が最初は表示されないために読み込まれない画像用のものです。
また、このメソッドはIEに対して機能しないことに注意してください(ajaxは通常、画像データの取得には使用されません)。
スプリッティング
他の人が述べたように、スプリッティングはさまざまな理由で非常にうまく機能しますが、それは意図されたほど良くありません。
しかし、不規則な形状を扱うのは難しいです。すべての新しい画像を新しい画像に結合することは、別の迷惑です。
<img>タグを使用したロージャックアプローチ
most definitiveのソリューションを探している場合は、私が今でも好むロージャックアプローチを採用する必要があります。ドキュメントの最後に画像への<img>リンクを作成し、width
およびheight
を1x1ピクセルに設定し、さらに非表示のdivに配置します。ページの最後にある場合、他のコンテンツの後に読み込まれます。
2013年1月の時点で、ここで説明した方法はどれも役に立たなかったため、代わりにChrome 25およびFirefox 18を使用してテストし、動作しました。jQueryと このプラグイン を使用します=ロードイベントの癖を回避するには:
function preload(sources, callback) {
if(sources.length) {
var preloaderDiv = $('<div style="display: none;"></div>').prependTo(document.body);
$.each(sources, function(i,source) {
$("<img/>").attr("src", source).appendTo(preloaderDiv);
if(i == (sources.length-1)) {
$(preloaderDiv).imagesLoaded(function() {
$(this).remove();
if(callback) callback();
});
}
});
} else {
if(callback) callback();
}
}
使用法:
preload(['/img/a.png', '/img/b.png', '/img/c.png'], function() {
console.log("done");
});
キャッシュが無効になっている場合、結果が混在することに注意してください。デフォルトでは、開発者ツールが開いているときにChromeになりますので、注意してください。
私の意見では、いくつかのライブラリで導入されたMultipart XMLHttpRequestを使用することは、今後数年間で推奨されるソリューションになるでしょう。ただしIE <v8、まだdata:uriをサポートしていません(IE8でもサポートは制限されており、最大32 kbが許可されています)。並列イメージプリロードの実装は次のとおりです- http: //code.google.com/p/core-framework/wiki/ImagePreloading 、フレームワークにバンドルされていますが、まだ見る価値があります。
これは昔からでしたので、私はまだ何人が画像のプリロードに興味を持っているのかわかりません。
私の解決策はさらにシンプルでした。
CSSを使用しました。
#hidden_preload {
height: 1px;
left: -20000px;
position: absolute;
top: -20000px;
width: 1px;
}
私のユースケースでは、プリロードしたいフルスクリーン画像のカルーセルがありました。ただし、画像は順番に表示され、読み込みに数秒かかることがあるため、順番に順番に読み込むことが重要です。
これには、非同期ライブラリのwaterfall()
メソッドを使用しました( https://github.com/caolan/async#waterfall )
_ // Preload all images in the carousel in order.
image_preload_array = [];
$('div.carousel-image').each(function(){
var url = $(this).data('image-url');
image_preload_array.Push(function(callback) {
var $img = $('<img/>')
$img.load(function() {
callback(null);
})[0].src = url;
});
});
async.waterfall(image_preload_array);
_
これは、関数の配列を作成することにより機能します。各関数には、配列内の次の関数を呼び出すために実行する必要があるパラメーターcallback()
が渡されます。 callback()
の最初のパラメーターはエラーメッセージで、null以外の値が指定された場合にシーケンスを終了するため、毎回nullを渡します。
ここでは、画像が読み込まれた後にフェードインする簡単なソリューションを紹介します。
function preloadImage(_imgUrl, _container){
var image = new Image();
image.src = _imgUrl;
image.onload = function(){
$(_container).fadeTo(500, 1);
};
}