2010-05-14 10 views
8

Mam trochę problemów z wypracowaniem, gdy obraz został załadowany.JQuery - Sprawdź, czy obraz jest załadowany?

Powiedziano mi, że następująca funkcja będzie działać, ale nic nie robi.

$("#photos img:first").load(function(){ 
    alert("Image loaded!"); 
}); 

Nie ma błędów w moim kodzie. Wszystko inne w moim skrypcie działa świetnie.

Mój HTML wygląda tak.

<div id="photos"> 
    <img src="../sample1.jpg" style="background-color:#000033" width="1" height="1" alt="Frog!"/> 
    <img src="../sample2.jpg" style="background-color:#999999" width="1" height="1" alt="Zooey!"/> 
</div> 

Czy mam nieprawidłową funkcję JQuery? Należy również zauważyć, że widoczność jest ukryta. Jednak nawet gdy jest widoczny, nie ma alarmu.

Wszelkie pomysły?

Odpowiedz

17

load wydarzeniem obrazu jest zwolniony, gdy jest załadowany (doh!), I krytycznie, jeśli nie zahaczyć swoją obsługi przed załadowaniem, twój przewodnik nie zostanie wywołany. Przeglądarki ładują zasoby równolegle, więc nie można być pewnym (nawet w przypadku zdarzenia jQuery ready, gdy DOM strony jest gotowy), że obraz nie został załadowany podczas działania kodu.

Można użyć właściwości obiektu obrazu complete wiedzieć, czy to już załadowany, więc:

var firstPhoto = $("#photos img:first"); 
if (firstPhoto[0].complete) { 
    // Already loaded, call the handler directly 
    handler(); 
} 
else { 
    // Not loaded yet, register the handler 
    firstPhoto.load(handler); 
} 
function handler() { 
    alert("Image loaded!"); 
} 

Może być nawet wyścigu w tym, jeśli przeglądarka w pytaniu naprawdę realizuje multi- ładowanie wątkowe, w którym może wystąpić ładowanie obrazu w innym wątku niż wątek Javascript.

Oczywiście, jeśli twój selektor dopasuje wiele obrazów, będziesz musiał sobie z tym poradzić; Twój selektor wygląda to miało pasuje tylko jeden, więc ...

Edycja Wersja ta pozwala na wiele zdjęć, a myślę obsługuje żadnych warunków wyścigu non-JavaScript (i oczywiście, w chwili obecnej nie ma warunków wyścigu javascript sama Javascript jest jednowątkowy w przeglądarkach [chyba użyć nowego web workers rzeczy]):

function onImageReady(selector, handler) { 
    var list; 

    // If given a string, use it as a selector; else use what we're given 
    list = typeof selector === 'string' ? $(selector) : selector; 

    // Hook up each image individually 
    list.each(function(index, element) { 
     if (element.complete) { 
      // Already loaded, fire the handler (asynchronously) 
      setTimeout(function() { 
       fireHandler.call(element); 
      }, 0); // Won't really be 0, but close 
     } 
     else { 
      // Hook up the handler 
      $(element).bind('load', fireHandler); 
     } 
    }); 

    function fireHandler(event) { 
     // Unbind us if we were bound 
     $(this).unbind('load', fireHandler); 

     // Call the handler 
     handler.call(this); 
    } 
} 

// Usage: 
onImageReady("#photos img:first"); 

kilka uwag:

  • Wywołanie zwrotne nie otrzymuje obiektu event; możesz to zmodyfikować, aby to zrobić, jeśli ci się podoba, ale oczywiście nie byłoby żadnego przypadku w przypadku, gdy obraz jest już załadowany, więc miałby ograniczoną użyteczność.
  • Prawdopodobnie użyjesz one zamiast bind i unbind, ale lubię klarowność i jestem paranoikiem.:-)
3

Użyj zdarzenia ready zamiast load.

+0

Aha, geniuszu. Wielkie dzięki. Zamierzam odejść i sprawdzić różnicę między tymi dwoma :) – JasonS

+0

Czy masz odniesienie do zdarzenia 'ready' ** zdjęć **? Jedyne "gotowe", które znam, to wydarzenie "DOM jest gotowe" jQuery, które jest zupełnie inne. –

+0

Niezupełnie, użyłem prób i błędów z dużym obrazem. – ThiefMaster

0

spróbuj tego:

$("#images img:last").one("load",function(){ 
     //do something  
} 

lub

$("#images img:last").one("ready",function(){ 
     //do something  
} 
+0

Zobacz uwagi dotyczące odpowiedzi ThiefMaster, naprawdę nie sądzisz, że istnieje zdarzenie "ready" dla obrazów, tylko dokumentów (syntetyczny, który dostarcza jQuery). –

Powiązane problemy