3

div があり、その div に HTML を挿入したいとします。HTML には 1 つ以上の画像が含まれます。

プレーンな JavaScript または jQuery を使用して、画像がいつ読み込まれたかを判断する方法はありますか?

では、次のようにすると、イベント リスナーを 1 つの要素に配置して、画像を含むコンテンツの準備が整ったことを通知できますか?

var html = "<p>Some text <img src='image.jpg' /></p><p>Some more text <img src='image2.jpg' /></p>";
$("div.output").html(html);

画像は毎回異なるため、JavaScript 画像オブジェクトを使用してプリロードすることはできません。

私が考えている 1 つの方法は、正規表現または jQuery を使用して HTML を実行し、すべての画像 URL を見つけてループし、それぞれに画像オブジェクトをプリロードすることです。すべてがプリロードされたら、HTML を出力 div に挿入します。

4

7 に答える 7

2

ロードする前に各画像にイベントを接続してカウントしない限りonload、すべての画像がいつロードされたかを簡単に知る方法はありません。

于 2012-05-07T18:52:39.280 に答える
1

IE 6-9、Chrome 19、および Firefox 3.6-10、Opera 10.10-11.52、Android 4、および iOS 5 でテストおよび動作するsを使用する比較的防弾の方法( demo ) を次に示します。Deferred

Deferred最初に、jQuery コレクション内の各要素の の配列を返す小さな jQuery プラグインを作成します。要素が読み込まれると、それぞれDeferredが解決されます。要素の読み込みに失敗した場合、または (オプションで) 数timeout秒以上かかる場合は拒否されます。

$.fn.loaded = function(opts) {
    var o = $.extend({timeout:10000}, opts) // Merge default options with supplied options
        , r = []; // Return value

    this.each(function() {
        var dfd = new $.Deferred(), el = $(this), to;
        if (o.timeout) to = setTimeout(function() {
            done();
            dfd.reject();
        }, o.timeout);
        el.bind('load.dfdl', function() {
            done();
            dfd.resolve();
        }).bind('error.dfdl', function() {
            done();
            dfd.reject();
        });

        function done() { // internal clean-up
            clearTimeout(to);
            el.unbind('.dfdl');
        }
        r.push(dfd.promise());
    });
    return r;
};

タイムアウトは、ブラウザが実際にイベントを発生させないケースを防ぎます。ここではデフォルトのタイムアウトを 10 秒に設定しました。現実の世界では、それを減らしたいと思うかもしれません。

ここで、例の画像として使用するランダムなサイズのプレース子猫を 10 個生成します。

var imgs=[];
for (var i = 0; i < 10; i++) imgs.push('<img src="http://placekitten.com/' + rnd() + '/' + rnd() + '"> ');
$('#imgs').html(imgs.join());

最後に、いくつかの魔法を使ってすべてをまとめます。

$.when.apply($, $('#imgs img').loaded({timeout:10000}) ).done(function() {
    alert('loaded successfully');
}).fail(function() {
    alert('load failed or timed out');
});

$.whenDeferredすべての子が解決されたときにのみ解決されるDeferredか、子が拒否されたときに拒否されるマスターを作成します。通常、それぞれを引数として渡す必要があるため ( s のDeferred配列を渡すことはサポートされていません)、配列を指定する必要があります。(あなたのアプリコードがよりきれいになるようにするかもしれません)Deferredapply$.whenall = function(dfds) { $.when.apply($,dfds); };$.whenall( $('#imgs img').loaded() )...

于 2012-05-07T20:39:33.670 に答える
0

私が考えている方法の1つは、正規表現またはjQueryを使用してHTMLを実行し、すべての画像URLを検索し、それらをループして、それぞれに画像オブジェクトをプリロードすることです。すべてがプリロードされたら、HTMLを出力divに挿入します。

var imagesLoaded = [];
var imagesErrored = [];

$('img').each(function() {
     $(this).load(function() {
         imagesLoaded.push($(this).attr("src"));
         if( (imagesLoaded.length + imagesErrored.length) == $('img').length ) {
             displayResults(imagesLoaded, imagesErrored);

         } 
     });
     $(this).error(function() {
         imagesErrored.push($(this).attr("src"));
         if( (imagesLoaded.length + imagesErrored.length) == $('img').length ) {
             displayResults(imagesLoaded, imagesErrored);
         } 

});

function displayResults(imagesLoaded, imagesErrored) {
    for(var i = 0; i < imagesLoaded.length; i++) {
        alert(imagesLoaded[i] + " has loaded successfully.");
        $('#myDiv').append("<img src='" + imagesLoaded[i] + "' />");
    }
    for(var i = 0; i < imagesErrored.length; i++) {
        alert(imagesLoaded[i] + " did NOT load successfully.");
    }
}

上記はすべての画像をループし、loadイベントを使用して画像が読み込まれたかどうかを確認します。エラーイベントを使用して、何らかの理由で正しく読み込まれなかったすべての画像のコレクションも取得します。すべての画像がプリロードされたら、「displayResults」関数でページに画像を挿入できます。これは、質問の最後の段落に大まかに基づいています。

ただし、正規表現はDOMを操作するための適切なツールではないため、正規表現は使用しません。幸い、JavaScriptとjQueryは、DOM操作と解析アクティビティを実行するために必要なツールを提供してくれます。

最後に、あなたの質問から、どの画像が正常に読み込まれたかを知りたいと思っていたようです。ロードイベントとエラーイベントから構築された上記のコレクションは、必要に応じてそれらの詳細を提供します。

于 2012-05-07T19:23:19.107 に答える
0

画像をhtmlに挿入した後、ロードハンドラーをバインドする必要があると思います。

デモ

    //Add image
    $('#result').append('<img src= "<Your_Image_URL>" width="300" height="300"/>');

    //Bind handler also add condition to not bind images that was not added before.
    $('#result').find('img').not('.loaded').on('load', function () {
        alert('Image Loaded');
        //Add code that you want to do after the image is added
    }).addClass('loaded');

また、画像で使用する場合は load イベントの注意事項に注意してください。

開発者が .load() ショートカットを使用して解決しようとする一般的な課題は、画像 (または画像のコレクション) が完全に読み込まれたときに関数を実行することです。これには注意すべき既知の警告がいくつかあります。これらは:

  1. クロスブラウザで一貫して確実に動作しない
  2. 画像の src が以前と同じ src に設定されている場合、WebKit で正しく起動しません。
  3. DOM ツリーを正しくバブルアップしない
  4. ブラウザのキャッシュに既に存在する画像の起動を停止することができます

参考: http ://api.jquery.com/load-event/

于 2012-05-07T19:03:04.447 に答える
0

これを試して:

$("#preload_div").html(
    '<img src="image.png" alt="preload" class="preload" width="0" height="0">'
);

イベント ハンドラーは画像にバインドできます。

$('preload').load(function () {
    var html = "<p>Some text <img src='image.jpg' /></p><p>Some more text <img src='image2.jpg' /></p>";
    $("div.output").html(html);
});

もちろん、すべての画像をループするには、各画像に.each()を組み込む必要があります。

編集: AJAX Web サイトの 1 つで、必要な次の画像をプリロードするため、ユーザーが「次へ」ボタンをクリックすると、新しいコンテンツに必要な画像が既にキャッシュされています。http://funl.es/p/1を参照

于 2012-05-07T18:52:53.640 に答える
0

jQuery の「on」イベント メカニズムの使用を検討しましたか? 「on」を使用すると、コンテナーと DOM に動的に追加されるときに、各画像に「load」ハンドラーを自動的にバインドできます。

リンク: 「on」関数の jQuery ドキュメント

1.7 より前の jQuery を使用している場合は、1.7 リリースで「on」が追加されたため、「live」関数を使用する必要があります。

リンク: 「ライブ」機能の jQuery ドキュメント (非推奨)

于 2012-05-07T21:34:58.057 に答える
-1

それを行う簡単な方法はないと思います。できることは、非表示の div にすべての画像をロードすることです ( display: none )。

画像を表示したい場合は、次のことができます。

$("#myDiv").show();
于 2012-05-07T18:56:26.377 に答える