他の人の質問を読んだことで
window.onload=...
私の質問に答えるでしょう。私はこれを試しましたが、ページが読み込まれた瞬間にコードが実行されます(画像が読み込まれた後ではありません)。
違いが生じる場合、画像はCDNからのものであり、相対的なものではありません。
誰かが解決策を知っていますか?(私はjQueryを使用していません)
他の人の質問を読んだことで
window.onload=...
私の質問に答えるでしょう。私はこれを試しましたが、ページが読み込まれた瞬間にコードが実行されます(画像が読み込まれた後ではありません)。
違いが生じる場合、画像はCDNからのものであり、相対的なものではありません。
誰かが解決策を知っていますか?(私はjQueryを使用していません)
最新のブラウザの簡単なハックは次のとおりです。
var imgs = document.images,
len = imgs.length,
counter = 0;
[].forEach.call( imgs, function( img ) {
if(img.complete)
incrementCounter();
else
img.addEventListener( 'load', incrementCounter, false );
} );
function incrementCounter() {
counter++;
if ( counter === len ) {
console.log( 'All images loaded!' );
}
}
すべての画像が読み込まれると、コンソールに「すべての画像が読み込まれました!」と表示されます。
このコードの機能:
incrementCounter
関数を実行しますincrementCounter
カウンターをインクリメントしますこのコードをクロスブラウザー方式で使用することはそれほど難しくはありませんが、このようにすっきりしています。
ワンライナーが欲しいですか?
Promise.all(Array.from(document.images).filter(img => !img.complete).map(img => new Promise(resolve => { img.onload = img.onerror = resolve; }))).then(() => {
console.log('images finished loading');
});
かなり下位互換性があり、Firefox52およびChrome49(Windows XP時代)でも動作します。ただし、IE11にはありません。
画像リストを絞り込みたい場合はdocument.images
、例えばに置き換えてください。document.querySelectorAll(...)
簡潔にするためにonload
とを使用します。要素のこれらのハンドラーが他の場所にも設定されている場合(可能性は低いですが、とにかく)、onerror
これはページ上の他のコードと競合する可能性があります。img
ページでそれらが使用されていないかどうかわからず、安全を確保したい場合は、パーツimg.onload = img.onerror = resolve;
をより長いパーツと交換してくださいimg.addEventListener('load', resolve); img.addEventListener('error', resolve);
。
また、すべての画像が正常に読み込まれたかどうか(壊れた画像がないかどうか)もテストされません。これが必要な場合は、さらに高度なコードを次に示します。
Promise.all(Array.from(document.images).map(img => {
if (img.complete)
return Promise.resolve(img.naturalHeight !== 0);
return new Promise(resolve => {
img.addEventListener('load', () => resolve(true));
img.addEventListener('error', () => resolve(false));
});
})).then(results => {
if (results.every(res => res))
console.log('all images loaded successfully');
else
console.log('some images failed to load, all finished loading');
});
すべての画像がロードされるか、ロードに失敗するまで待機します。
最初の壊れた画像で、早期に失敗したい場合:
Promise.all(Array.from(document.images).map(img => {
if (img.complete)
if (img.naturalHeight !== 0)
return Promise.resolve();
else
return Promise.reject(img);
return new Promise((resolve, reject) => {
img.addEventListener('load', resolve);
img.addEventListener('error', () => reject(img));
});
})).then(() => {
console.log('all images loaded successfully');
}, badImg => {
console.log('some image failed to load, others may still be loading');
console.log('first broken image:', badImg);
});
2つの最新のコードブロックはnaturalHeight
、すでにロードされている画像の中から壊れた画像を検出するために使用されます。この方法は一般的に機能しますが、いくつかの欠点があります。画像のURLがCSScontent
プロパティを介して設定されている場合、および画像がサイズが指定されていないSVGである場合、機能しないと言われます。この場合、画像の読み込みを開始する前にイベントハンドラーを設定できるように、コードをリファクタリングする必要があります。これは、HTMLで直接指定するか、JavaScriptで要素を作成することonload
で実行できます。もう1つの方法は、HTMLのように設定し、ハンドラーをアタッチした後に実行することです。onerror
img
src
data-src
img.src = img.dataset.src
Promise Patternは、この問題を可能な限り最善の方法で解決します。when.jsは、すべての画像の読み込みの問題を解決するためのオープンソースライブラリです。
function loadImage (src) {
var deferred = when.defer(),
img = document.createElement('img');
img.onload = function () {
deferred.resolve(img);
};
img.onerror = function () {
deferred.reject(new Error('Image not found: ' + src));
};
img.src = src;
// Return only the promise, so that the caller cannot
// resolve, reject, or otherwise muck with the original deferred.
return deferred.promise;
}
function loadImages(srcs) {
// srcs = array of image src urls
// Array to hold deferred for each image being loaded
var deferreds = [];
// Call loadImage for each src, and push the returned deferred
// onto the deferreds array
for(var i = 0, len = srcs.length; i < len; i++) {
deferreds.push(loadImage(srcs[i]));
// NOTE: We could push only the promise, but since this array never
// leaves the loadImages function, it's ok to push the whole
// deferred. No one can gain access to them.
// However, if this array were exposed (e.g. via return value),
// it would be better to push only the promise.
}
// Return a new promise that will resolve only when all the
// promises in deferreds have resolved.
// NOTE: when.all returns only a promise, not a deferred, so
// this is safe to expose to the caller.
return when.all(deferreds);
}
loadImages(imageSrcArray).then(
function gotEm(imageArray) {
doFancyStuffWithImages(imageArray);
return imageArray.length;
},
function doh(err) {
handleError(err);
}
).then(
function shout (count) {
// This will happen after gotEm() and count is the value
// returned by gotEm()
alert('see my new ' + count + ' images?');
}
);
ページが読み込まれると起動するため、使用window.onload
は機能しませんが、画像はこの読み込み済みの定義に含まれていません。
これに対する一般的な解決策は、ImagesLoadedjQueryプラグインです。
jQueryをまったく使用しないことに熱心な場合は、少なくともこのプラグインを純粋なJavascriptに変換してみてください。93行の重要なコードと適切なコメントがあれば、それを達成するのは難しい作業ではありません。
処理を行う関数をコールバックできるonloadイベントを画像に設定できます...すべての画像が読み込まれた場合の処理方法に関して、次のメカニズムのいずれかが機能するかどうかはわかりません。
onloadが呼び出された画像の数をカウントする関数があります。これがページ上の画像の総数と等しい場合は、必要な処理を実行します。
<title>Pre Loading...</title>
</head>
<style type="text/css" media="screen"> html, body{ margin:0;
padding:0; overflow:auto; }
#loading{ position:fixed; width:100%; height:100%; position:absolute; z-index:1; ackground:white url(loader.gif) no-repeat center; }**
</style>
<script> function loaded(){
document.getElementById("loading").style.visibility = "hidden"; }
</script>
<body onload="loaded();"> <div id="loading"></div>
<img id="img" src="avatar8.jpg" title="AVATAR" alt="Picture of Avatar
movie" />
</body>
私はBaz1ngaが言ったのと同じことを提案しようとしていました。
また、絶対確実ではないが保守が容易な別の可能なオプションは、最も重要/最大のイメージを選択し、そのイメージにのみonloadイベントをアタッチすることです。ここでの利点は、後でページに画像を追加する場合に変更するコードが少なくなることです。
これはうまく機能します:
$(function() {
$(window).bind("load", function() {
// code here
});
});