Zdarzenie jQuery dla załadowanych obrazów

96

Czy można wykryć, kiedy wszystkie obrazy są ładowane za pośrednictwem zdarzenia jQuery?

W idealnym przypadku powinien istnieć plik

$(document).idle(function()
{
}

lub

$(document).contentLoaded(function()
{
}

Ale nie mogę znaleźć czegoś takiego.

Pomyślałem o dołączeniu takiego wydarzenia:

$(document).ready(function()
{
    var imageTotal = $('img').length;
    var imageCount = 0;        
    $('img').load(function(){if(++imageCount == imageTotal) doStuff();});
}

Ale czy to się zepsuje, jeśli obraz się nie załaduje? Bardzo ważne jest, aby wywołać metodę we właściwym czasie.

Antony Carthy
źródło
9
Dlaczego nie używasz zdarzenia onload: $ (window) .load (doStuff)? Onload będzie jednak czekać również na inne zasoby (np. Skrypty, arkusze stylów i flash), a nie tylko na obrazy, co może, ale nie musi, być dla Ciebie w porządku.
moff
Dołączenie zdarzenia load do wszystkich tagów img, tak jak w przykładowym kodzie, powinno działać. Jeśli załadowanie obrazu nie powiedzie się, funkcja doStuff () nie zostanie wywołana, ale wydaje się to rozsądne, biorąc pod uwagę wymaganie, że wszystkie obrazy muszą zostać załadowane.
Steve Goodman
2
Metoda .load () jest przestarzała od wersji jQuery 1.8. Zobacz to: stackoverflow.com/questions/3877027/ ...
fiorix

Odpowiedzi:

116

Zgodnie z dokumentacją jQuery istnieje szereg zastrzeżeń dotyczących używania zdarzenia load z obrazami. Jak zauważono w innej odpowiedzi, wtyczka ahpi.imgload.js jest zepsuta, ale powiązany z nią sens Paula Irisha nie jest już utrzymywany.

Według Paula Irisha, wtyczka kanoniczna do wykrywania zdarzeń zakończenia ładowania obrazu jest teraz dostępna pod adresem:

https://github.com/desandro/imagesloaded

johnpolacek
źródło
4
To jest odpowiedź - obsługuje wiele obrazów, obrazy w pamięci podręcznej, dziwactwa przeglądarki, uszkodzone obrazy i jest aktualne. Piękny.
Yarin
7
przetestowałem to dzisiaj. był gotowy do pracy w 2 minuty.
CodeToad,
Zgadzam się z @Yarin, dobra dokumentacja, łatwa w użyciu, wielokrotna, buforowana, uszkodzona i aktualna. Kocham to.
johntrepreneur,
Jednak z drugiej strony imagesLoaded nie obsługuje IE7, jeśli jest to dla Ciebie ważne.
johntrepreneur
1
Szybka i prosta 2-wierszowa poprawka umożliwiająca załadowanie obrazów w przeglądarce IE7 .
johntrepreneur
63

Jeśli chcesz sprawdzić nie wszystkie obrazy, ale konkretny (np. Obraz, który zastąpiłeś dynamicznie po ukończeniu DOM), możesz użyć tego:

$('#myImage').attr('src', 'image.jpg').on("load", function() {  
  alert('Image Loaded');  
});  
rsc
źródło
70
Uważaj, ponieważ load()nie zostanie wywołany, gdy obraz jest już załadowany. Może się to łatwo zdarzyć, gdy obraz znajduje się w pamięci podręcznej przeglądarki użytkownika. Możesz sprawdzić, czy obraz jest już załadowany za pomocą $('#myImage').prop('complete'), co zwraca wartość true po załadowaniu obrazu.
Blaise,
6
Dlaczego ma tak wiele głosów, skoro a) nie odpowiada na jego pytanie ib) poza tym daje kiepskie rozwiązanie? (Chociaż prawidłowa odpowiedź brzmi @ johnpolacek i ma 1 głos)
Yarin
5
OSTRZEŻENIE!!!!!!!!!!!!!!! To nie jest poprawna odpowiedź. johnpolacek ma poprawną odpowiedź. Zagłosuj na jego odpowiedź.
mrbinky3000
4
Te zastrzeżenia nie wydają się już mieć znaczenia, z wyjątkiem bardzo szczególnych okoliczności: Webkit, gdy zmienisz źródło obrazu na dokładnie to samo źródło co poprzednio. W przypadku obrazów, które właśnie dodałeś do DOM, $ (...). Load () powinno wystarczyć. Testowane w aktualnym FF i Chrome oraz IE6-9: jsfiddle.net/b9chris/tXVCe/2
Chris Moschini
1
+1 Działa dobrze, gdy (wiesz o tym) obraz nie znajduje się w pamięci podręcznej przeglądarki.
Lode
28

Możesz użyć mojej wtyczki waitForImages do obsługi tego ...

$(document).waitForImages(function() {
   // Loaded.
});

Zaletą tego jest to, że możesz zlokalizować go na jednym elemencie nadrzędnym i opcjonalnie może wykrywać obrazy, do których odwołuje się CSS.

To jednak tylko wierzchołek góry lodowej, sprawdź dokumentację, aby uzyskać więcej funkcji.

Alex
źródło
Cześć Alex, wygląda obiecująco. Ale tak jak wspomniane w odpowiedziach i komentarzach johnpolacek i hirisov, czy obejmuje to przypadek, gdy obraz jest już w pamięci podręcznej przeglądarki?
SexyBeast
Mam proces, który tworzy obraz i ładuje go dynamicznie po załadowaniu strony i musiałem pokazać moduł ładujący Ajax, gdy użytkownik czeka. Ta wtyczka działa idealnie w tym przypadku użycia. Musisz jednak wywołać tę funkcję po ustawieniu właściwości img src!
John Livermore
20

Użycie jQuery $ (). Load () jako modułu obsługi zdarzeń IMG nie jest gwarantowane. Jeśli obraz zostanie załadowany z pamięci podręcznej, niektóre przeglądarki mogą nie uruchomić zdarzenia. W przypadku (starszych?) Wersji przeglądarki Safari, jeśli zmienisz właściwość SRC elementu IMG na tę samą wartość , zdarzenie onload NIE zostanie uruchomione.

Wygląda na to, że jest to rozpoznane w najnowszym jQuery (1.4.x) - http://api.jquery.com/load-event - cytując:

Możliwe, że zdarzenie ładowania nie zostanie wywołane, jeśli obraz zostanie załadowany z pamięci podręcznej przeglądarki. Aby uwzględnić tę możliwość, możemy użyć specjalnego zdarzenia ładowania, które jest uruchamiane natychmiast, gdy obraz jest gotowy. event.special.load jest obecnie dostępny jako wtyczka.

Dostępna jest teraz wtyczka rozpoznająca ten przypadek, a właściwość „complete” przeglądarki IE dla elementów IMG jest ładowana: http://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js

jschrab
źródło
16

Zgodnie z tą odpowiedzią możesz użyć zdarzenia load jQuery na windowobiekcie zamiast document:

jQuery(window).load(function() {
    console.log("page finished loading now.");
});

Zostanie to uruchomione po załadowaniu całej zawartości strony. Różni się to od tego, jQuery(document).load(...)które jest uruchamiane po zakończeniu ładowania DOM.

Tomek
źródło
To jest dokładnie to, czego szukałem!
Eric K
4

imagesLoaded Plugin to dobry wybór , jeśli potrzebujesz rozwiązania obsługującego różne przeglądarki

 $("<img>", {src: 'image.jpg'}).imagesLoaded( function( $images, $proper, $broken ){
 if($broken.length > 0){
 //Error CallBack
 console.log('Error');
 }
 else{
 // Load CallBack
 console.log('Load');
 }
 });

Jeśli potrzebujesz tylko obejścia IE, to wystarczy

 var img = $("<img>", {
    error: function() {console.log('error'); },
    load: function() {console.log('load');}
    });
  img.attr('src','image.jpg');
Jaideep Singh
źródło
2

W przypadku obrazów tego samego pochodzenia możesz użyć:

$.get('http://www.your_domain.com/image.jpg', imgLoaded);

function imgLoaded(){
    console.log(this, 'loaded');
}
vsync
źródło
0
  function CheckImageLoadingState()
  {
     var counter = 0;
     var length = 0;

     jQuery('#siteContent img').each(function() 
     {
        if(jQuery(this).attr('src').match(/(gif|png|jpg|jpeg)$/))
          length++;
     });

     jQuery('#siteContent img').each(function() 
     {  
        if(jQuery(this).attr('src').match(/(gif|png|jpg|jpeg)$/))
        {
           jQuery(this).load(function() 
           {
           }).each(function() {
              if(this.complete) jQuery(this).load();
            });
        }
        jQuery(this).load(function()
        {
           counter++;
           if(counter === length) 
           {  
              //function to call when all the images have been loaded
              DisplaySiteContent();
           }
        });
     });
  }
doofer
źródło
0
$( "img.photo" ).load(function() {

    $(".parrentDiv").css('height',$("img.photo").height());
    // very simple

}); 
Erfan Safarpoor
źródło
0

Stworzyłem własny skrypt, ponieważ znalazłem wiele wtyczek, które były dość rozdęte i po prostu chciałem, aby działał tak, jak chciałem. Mój sprawdza, czy każdy obraz ma wysokość (wysokość obrazu natywnego). Połączyłem to z funkcją $ (window) .load (), aby obejść problemy z buforowaniem.

Skomentowałem to dość mocno, więc powinno być interesujące, nawet jeśli go nie używasz. U mnie działa idealnie.

Bez zbędnych ceregieli, oto jest:

skrypt imgLoad.js.

3Dom
źródło
0

Czekam na załadowanie wszystkich obrazów ...
Znalazłem odpowiedź na mój problem z jfriend00 tutaj jquery: jak odsłuchać zdarzenie załadowanego obrazu z jednego kontenera div? .. i „if (this.complete)”
Czekam na załadowanie wszystkich rzeczy i niektóre prawdopodobnie w pamięci podręcznej! .. i dodałem zdarzenie „błąd” ... działa solidnie we wszystkich przeglądarkach

$(function() { // Wait dom ready
    var $img = $('img'), // images collection
        totalImg = $img.length,
        waitImgDone = function() {
            totalImg--;
            if (!totalImg) {
                console.log($img.length+" image(s) chargée(s) !");
            }
        };
    $img.each(function() {
        if (this.complete) waitImgDone(); // already here..
        else $(this).load(waitImgDone).error(waitImgDone); // completed...
    });
});

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

molokoloco
źródło