2010-05-14 29 views
8

Estoy teniendo problemas para resolver el problema cuando se cargó una imagen.JQuery - ¿Verificar cuando se carga la imagen?

Me han dicho que la siguiente función funcionará pero no está haciendo nada.

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

No hay ningún error en mi código. Todo lo demás en mi script funciona muy bien.

Mi HTML tiene este aspecto.

<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> 

¿Tengo la función JQuery incorrecta? También se debe tener en cuenta que la visibilidad está configurada como oculta. Sin embargo, incluso cuando está visible, no hay alerta.

¿Alguna idea?

Respuesta

17

El load caso de una imagen se dispara cuando está cargada (DOH!), Y crítica, si no conectó su manejador antes de se carga, no se llamará a su controlador. Los navegadores cargarán recursos en paralelo, por lo que no puedes estar seguro (incluso en el evento ready de jQuery que el DOM está listo) de que la imagen no se ha cargado cuando se ejecuta el código.

Usted puede utilizar la propiedad complete del objeto en la imagen para saber si ya se ha cargado, por lo que:

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!"); 
} 

Incluso puede haber una condición de carrera en el que, si el navegador en cuestión realmente implementa múltiples carga enhebrada donde la carga de la imagen puede ocurrir en un hilo diferente al hilo de Javascript.

Por supuesto, si su selector coincidirá con varias imágenes, tendrá que manejar eso; el selector se ve como se supone que debe coincidir sólo uno, así que ...

Editar Esta versión permite múltiples imágenes, y yo creo que maneja cualquier condiciones de carrera no Javascript (y, por supuesto, en la actualidad hay son no hay condiciones de carrera Javascript; sí, JavaScript es un único subproceso en los navegadores [a menos que utilice la nueva web workers cosas]):

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"); 

Un par de notas:

  • La devolución de llamada no obtiene el objeto event; podría modificarlo para hacerlo si quisiera, pero por supuesto, no habría ningún evento en el caso de que la imagen ya esté cargada, por lo que sería de utilidad limitada.
  • Probablemente podría usar one en lugar de bind y unbind, pero me gusta la claridad y soy paranoico.:-)
3

Utilice el evento ready en lugar del load.

+0

Aha, genius. Muchas gracias. Voy a salir y buscar la diferencia entre los dos :) – JasonS

+0

¿Tiene una referencia para el evento 'listo' ** de imágenes **? El único 'listo' que conozco es el evento de jQuery" el DOM está listo ", que es completamente diferente. –

+0

No realmente, he usado prueba y error con una imagen grande. – ThiefMaster

0

probar esto:

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

o

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

Ver las notas en la respuesta de ThiefMaster, realmente no creo que haya un evento 'listo' para imágenes, solo documentos (el uno sintético que proporciona jQuery). –

0
$("#images img:last").on('load',function(){ 
    //do smth 
}); 
+0

esto debería funcionar – user2300701

Cuestiones relacionadas