39

他の人の質問を読んだことで

window.onload=...

私の質問に答えるでしょう。私はこれを試しましたが、ページが読み込まれた瞬間にコードが実行されます(画像が読み込まれた後ではありません)。

違いが生じる場合、画像はCDNからのものであり、相対的なものではありません。

誰かが解決策を知っていますか?(私はjQueryを使用していません)

4

8 に答える 8

62

最新のブラウザの簡単なハックは次のとおりです。

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カウンターをインクリメントします
  • カウンターが画像の長さに達した場合、それはすべての画像が読み込まれていることを意味します

このコードをクロスブラウザー方式で使用することはそれほど難しくはありませんが、このようにすっきりしています。

于 2012-06-17T13:37:06.357 に答える
53

ワンライナーが欲しいですか?

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のように設定し、ハンドラーをアタッチした後に実行することです。onerrorimgsrcdata-srcimg.src = img.dataset.src

于 2020-03-31T11:49:17.177 に答える
17

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?');
    }
);
于 2012-06-17T15:33:40.793 に答える
3

ページが読み込まれると起動するため、使用window.onloadは機能しませんが、画像はこの読み込み済みの定義に含まれていません。

これに対する一般的な解決策は、ImagesLoadedjQueryプラグインです。

jQueryをまったく使用しないことに熱心な場合は、少なくともこのプラグインを純粋なJavascriptに変換してみてください。93行の重要なコードと適切なコメントがあれば、それを達成するのは難しい作業ではありません。

于 2012-06-17T12:36:54.530 に答える
1

処理を行う関数をコールバックできるonloadイベントを画像に設定できます...すべての画像が読み込まれた場合の処理​​方法に関して、次のメカニズムのいずれかが機能するかどうかはわかりません。

onloadが呼び出された画像の数をカウントする関数があります。これがページ上の画像の総数と等しい場合は、必要な処理を実行します。

于 2012-06-17T12:45:41.177 に答える
1
 <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>
于 2012-06-17T13:08:57.607 に答える
-1

私はBaz1ngaが言ったのと同じことを提案しようとしていました。

また、絶対確実ではないが保守が容易な別の可能なオプションは、最も重要/最大のイメージを選択し、そのイメージにのみonloadイベントをアタッチすることです。ここでの利点は、後でページに画像を追加する場合に変更するコードが少なくなることです。

于 2012-06-17T12:51:53.273 に答える
-3

これはうまく機能します:

$(function() {
 $(window).bind("load", function() {
    // code here
 });
});
于 2019-06-12T12:58:31.500 に答える