Bir şey çalıştırmadan önce jQuery'den tüm görüntülerin yüklenmesini beklemenin resmi yolu


641

Bunu yaptığınızda jQuery'de:

$(function() {
   alert("DOM is loaded, but images not necessarily all loaded");
});

DOM'un yüklenmesini bekler ve kodunuzu yürütür. Tüm görüntüler yüklenmemişse yine de kodu yürütür. Bu, öğeleri gösterme veya gizleme veya etkinlik ekleme gibi DOM öğelerini başlatırsak istediğimiz şeydir.

Diyelim ki biraz animasyon istiyorum ve tüm görüntüler yüklenene kadar çalışmasını istemiyorum. JQuery'de bunu yapmanın resmi bir yolu var mı?

Sahip olduğum en iyi yol kullanmak <body onload="finished()">ama bunu yapmak zorunda kalmadıkça bunu yapmak istemiyorum.

Not: Internet Explorer'da jQuery 1.3.1'de , içindeki kodu çalıştırmadan önce tüm görüntülerin yüklenmesini bekleyen bir hata vardır $function() { }. Bu platformu kullanıyorsanız, yukarıda açıklanan doğru davranış yerine aradığım davranışı elde edersiniz.


3
çalışmıyor $("img").load()mu?
Lucas

1
Boyut niteliklerini ayarlarsanız, bu boyutlara dayanan hazır fonksiyonda bazı kodları güvenle yürütebileceğinizi belirtmek gerekir. Php ile yükleme sırasında phb.net/manual/en/function.getimagesize.php ile onları db içinde saklamak veya tarayıcıya çıktı önce kapmak olabilir .
Alqin

inanılmaz bir iş yapmak bir şey istiyorsanız, aşağıdaki bu cevapta belirtilen son derece iyi ve popüler imagesloaded javascript kütüphanesine göz atın stackoverflow.com/a/26458347/759452
Adrien

"Burada resmi bir yol dışında bir şey bulmaya geldim."
Léon Pelletier

Yanıtlar:


1035

JQuery ile, kullanmak $(document).ready()başladığında, bir şey yürütmek için DOM yüklenir ve $(window).on("load", handler)tüm diğer şeyler resimler gibi, hem yüklendiğinde şey yürütmek için.

jollyrogerJPEG dosyalarınız (veya başka uygun dosyalarınız) varsa, fark aşağıdaki eksiksiz HTML dosyasında görülebilir :

<html>
    <head>
        <script src="jquery-1.7.1.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                alert ("done");
            });
        </script>
    </head><body>
        Hello
        <img src="jollyroger00.jpg">
        <img src="jollyroger01.jpg">
        // : 100 copies of this
        <img src="jollyroger99.jpg">
    </body>
</html>

Bununla, DOM o noktada hazır olduğundan uyarı kutusu görüntüler yüklenmeden önce görünür. Daha sonra değiştirirseniz:

$(document).ready(function() {

içine:

$(window).on("load", function() {

resimler yüklendikten sonra uyarı kutusu görünmez .

Bu nedenle, sayfanın tamamı hazır olana kadar beklemek için aşağıdaki gibi bir şey kullanabilirsiniz:

$(window).on("load", function() {
    // weave your magic here.
});

32
şaplak alın + +1 tamamen unuttu. $ (window) .load () resimler yapılana kadar tetiklenmez.
Paolo Bergantino

10
Ben de aynısını yaptım. Hatta benim olduğumu bilmeyen ve hala anlamayan bir cevap okuyun.
Rimian

24
Sadece bir not - bu Chromium altında çalışmıyor (ve Chrome'u varsayıyorum). $ (Window) .ready olayı, görüntüler tamamlanmadan önce $ (document) .ready ile aynı gibi görünüyor.
Nathan Crause

24
ancak bu $ (window) .load (function ())
TJ-

3
@KyorCode Sadece IE'deki görüntülerin önbelleğe alındığından emin değil misiniz? Böyle bir durumda, bir "yükleme" olayı başlatmazlar. Bu makale, bu sorunun üstesinden gelmenize yardımcı olur.
Jamie Barker

157

Görüntüler öğelere yüklendiğinde geri çağrıları veya yüklenen görüntü başına bir kez ateşleyebilen bir eklenti yazdım.

$(window).load(function() { .. })Kontrol edilecek herhangi bir seçiciyi tanımlamanıza izin vermesi dışında buna benzer . Yalnızca #content(örneğin) içindeki tüm görüntülerin ne zaman yüklendiğini bilmek istiyorsanız , bu sizin için bir eklentidir.

Ayrıca CSS başvurulan görüntüleri gibi yüklenmesini destekler background-image, list-style-imagevb

waitForImages jQuery eklentisi

Örnek Kullanım

$('selector').waitForImages(function() {
    alert('All images are loaded.');
});

JsFiddle örneği .

GitHub sayfasında daha fazla belge bulunmaktadır.


1
Teşekkür ederim!! $ .load () benim için çalışmıyor, ama bu hile mükemmel.
Fraxtil

Chrome Sürüm 22.0.1229.94 ve bu eklentiyi kullanıyorum ve waitFormImages içindeki yüklü görüntülerden ofsetleri okumaya çalıştım: ('img selector').each(function(index) { var offset = $(this).offset(); ...});ancak offset.top hala sıfır. Neden?
basZero

1
@basZero Daha fazla bağlam olmadan söylemek zor. Lütfen Sorunlar sayfasında bir sorun oluşturun .
alex

Görüntüler ortaya çıktığında benim için çalışmıyor. Any1 bunun için bir geçici çözüm sunuyor mu?
Mandeep Jain

2
Temelde görüntülere analogdurYüklendi ancak srcsets ile de çalışır. Tam olarak ne aradım! Harika bir eklenti!
Fabian Schöner

48

$(window).load()yalnızca sayfa ilk yüklendiğinde çalışır. Dinamik şeyler yapıyorsanız (örnek: düğmesine tıklayın, bazı yeni görüntülerin yüklenmesini bekleyin) bu işe yaramaz. Bunu başarmak için eklentimi kullanabilirsiniz:

gösteri

İndir

/**
 *  Plugin which is applied on a list of img objects and calls
 *  the specified callback function, only when all of them are loaded (or errored).
 *  @author:  H. Yankov (hristo.yankov at gmail dot com)
 *  @version: 1.0.0 (Feb/22/2010)
 *  http://yankov.us
 */

(function($) {
$.fn.batchImageLoad = function(options) {
    var images = $(this);
    var originalTotalImagesCount = images.size();
    var totalImagesCount = originalTotalImagesCount;
    var elementsLoaded = 0;

    // Init
    $.fn.batchImageLoad.defaults = {
        loadingCompleteCallback: null, 
        imageLoadedCallback: null
    }
    var opts = $.extend({}, $.fn.batchImageLoad.defaults, options);

    // Start
    images.each(function() {
        // The image has already been loaded (cached)
        if ($(this)[0].complete) {
            totalImagesCount--;
            if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);
        // The image is loading, so attach the listener
        } else {
            $(this).load(function() {
                elementsLoaded++;

                if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);

                // An image has been loaded
                if (elementsLoaded >= totalImagesCount)
                    if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
            });
            $(this).error(function() {
                elementsLoaded++;

                if (opts.imageLoadedCallback) opts.imageLoadedCallback(elementsLoaded, originalTotalImagesCount);

                // The image has errored
                if (elementsLoaded >= totalImagesCount)
                    if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
            });
        }
    });

    // There are no unloaded images
    if (totalImagesCount <= 0)
        if (opts.loadingCompleteCallback) opts.loadingCompleteCallback();
};
})(jQuery);

Herkesin BatchImagesLoad eklentisine bir kullanım örneğine ihtiyacı olması durumunda: yankov.us/batchImageLoad
Jonathan Marzullo

1
Yani saygısızlık yok ama eklentinizin güvenilirliği konusunda sözünüze güvenemezsiniz. Bahsedildiği üzere Yevgeniy Afanasyevbireyin cevap , imagesLoaded bu & diğer birçok köşe durumlarda birlikte bahsedilerek kullanım örneğini kapsar de çok daha iyi bir iş yok (çözüldü github sorunları bakınız) .
Adrien Be

19

$(window).loadYangınlardan sonra istenen tek bir görüntünün indirme işleminin tamamlandığını bildirmek isteyenler için resim öğesinin loadetkinliğini kullanabilirsiniz.

Örneğin:

// create a dialog box with an embedded image
var $dialog = $("<div><img src='" + img_url + "' /></div>");

// get the image element (as a jQuery object)
var $imgElement = $dialog.find("img");

// wait for the image to load 
$imgElement.load(function() {
    alert("The image has loaded; width: " + $imgElement.width() + "px");
});

13

Şimdiye kadar verilen cevapların hiçbiri en basit çözüm gibi görünmüyordu.

$('#image_id').load(
  function () {
    //code here
});

Bununla ilgili güzel olan şey, tek tek görüntüleri yükler yüklemez tetikleyebilmenizdir.
Top Cat

6

imagesLoaded.jsJavascript kütüphanesini kullanmanızı tavsiye ederim .

Neden jQuery's kullanmıyorsunuz $(window).load()?

Https://stackoverflow.com/questions/26927575/why-use-imagesloaded-javascript-library-versus-jquerys-window-load/26929951 adresinde belirtildiği gibi

Bu bir kapsam meselesi. imagesLoaded, görüntülerin bir grubunu hedefleyen verir oysa $(window).load()hedeflere bütün varlıklar - tüm görüntüler, nesneler, Js ve .css dosyaları ve hatta iframe'lerin dahil. Büyük olasılıkla, imagesLoaded, $(window).load()daha küçük bir varlık grubunu hedeflemesinden daha erken tetiklenir .

Imagesloaded kullanmak için diğer iyi nedenler

  • IE8 + tarafından resmi olarak desteklenmektedir
  • lisans: MIT Lisansı
  • bağımlılıklar: hiçbiri
  • ağırlık (küçültülmüş ve sıkıştırılmış): 7kb küçültülmüş (hafif!)
  • download builder (kilo vermeye yardımcı olur): gerek yok, zaten küçük
  • Github'da: EVET
  • topluluk ve katkıda bulunanlar: oldukça büyük, 4000+ üye, ancak yalnızca 13 katılımcı
  • Tarihçe ve katkıları: göreceli olarak eski (2010'dan beri) ama hala aktif proje

kaynaklar


4

JQuery ile ben bu geliyor ...

$(function() {
    var $img = $('img'),
        totalImg = $img.length;

    var waitImgDone = function() {
        totalImg--;
        if (!totalImg) alert("Images loaded!");
    };

    $('img').each(function() {
        $(this)
            .load(waitImgDone)
            .error(waitImgDone);
    });
});

Demo: http://jsfiddle.net/molokoloco/NWjDb/


Tarayıcı, görüntünün önbelleğe alındığı anlamına gelen 304 Not Mofified yanıtı döndürürse bunun düzgün çalışmadığını öğrendim.
JohnyFree

1

Yüklü PACKAGED v3.1.8 (simge durumuna küçültüldüğünde 6,8 Kb). Nispeten eskidir (2010'dan beri) ama hala aktif bir projedir.

Bunu github'da bulabilirsiniz: https://github.com/desandro/imagesloaded

Resmi siteleri: http://imagesloaded.desandro.com/

Neden kullanmaktan daha iyidir:

$(window).load() 

Çünkü görüntüleri dinamik olarak yüklemek isteyebilirsiniz, şöyle : jsfiddle

$('#button').click(function(){
    $('#image').attr('src', '...');
});

1
Aslında, imagesloaded src özellik değeri çapraz tarayıcısının değişimini desteklemez. Her seferinde yeni bir görüntü öğesi oluşturmalısınız. Firefox'ta deneyin ve sorunun ortaya çıktığını göreceksiniz.
Adrien Be

İyi bir nokta, henüz Google Chrome ve IE-11'de test ettim. Çalışıyordu. Teşekkürler.
Yevgeniy Afanasyev

Ben, "Sen imagesloaded ile neleri yapamaz" Github üzerinde imagesLoaded ilgili sorunu bkz noktasında sorum stackoverflow.com/q/26927575 bu çapraz tarayıcı sorunu eklediniz mi github.com/desandro/imagesloaded/issues/121
Adrien Be

1

Bu şekilde, gövdedeki veya başka bir kaptaki (seçiminize bağlı olan) tüm görüntüler yüklendiğinde bir eylem gerçekleştirebilirsiniz. SAF JQUERY, eklenti gerekmez.

var counter = 0;
var size = $('img').length;

$("img").load(function() { // many or just one image(w) inside body or any other container
    counter += 1;
    counter === size && $('body').css('background-color', '#fffaaa'); // any action
}).each(function() {
  this.complete && $(this).load();        
});

0

Benim çözümüm molokoloco'ya benzer . JQuery işlevi olarak yazılmıştır:

$.fn.waitForImages = function (callback) {
    var $img = $('img', this),
        totalImg = $img.length;

    var waitImgLoad = function () {
        totalImg--;
        if (!totalImg) {
            callback();
        }
    };

    $img.each(function () {
        if (this.complete) { 
            waitImgLoad();
        }
    })

    $img.load(waitImgLoad)
        .error(waitImgLoad);
};

misal:

<div>
    <img src="img1.png"/>
    <img src="img2.png"/>
</div>
<script>
    $('div').waitForImages(function () {
        console.log('img loaded');
    });
</script>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.