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.:-)
Aha, genius. Muchas gracias. Voy a salir y buscar la diferencia entre los dos :) – JasonS
¿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. –
No realmente, he usado prueba y error con una imagen grande. – ThiefMaster