paginas - ¿Cómo puedo determinar si una imagen se ha cargado usando JavaScript/jQuery?
funcion load javascript (12)
Estoy escribiendo algo de Javascript para cambiar el tamaño de la imagen grande para que quepa en la ventana del navegador del usuario. (No controlo el tamaño de las imágenes de origen por desgracia).
Entonces algo como esto estaría en el HTML:
<img id="photo"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
¿Hay alguna manera de determinar si se ha descargado la imagen src
en una etiqueta img
?
Lo necesito porque me encuentro con un problema si $(document).ready()
se ejecuta antes de que el navegador cargue la imagen. $("#photo").width()
y $("#photo").height()
devolverán el tamaño del marcador de posición (el texto alternativo). En mi caso, esto es algo así como 134 x 20.
En este momento solo estoy verificando si la altura de la foto es menos de 150, y supongo que si es así, solo es texto alternativo. Pero esto es todo un truco, y se rompería si una foto tiene menos de 150 píxeles de alto (no es probable en mi caso particular), o si el texto alternativo tiene más de 150 píxeles de alto (posiblemente en una pequeña ventana del navegador) .
Editar: Para cualquiera que quiera ver el código:
$(function()
{
var REAL_WIDTH = $("#photo").width();
var REAL_HEIGHT = $("#photo").height();
$(window).resize(adjust_photo_size);
adjust_photo_size();
function adjust_photo_size()
{
if(REAL_HEIGHT < 150)
{
REAL_WIDTH = $("#photo").width();
REAL_HEIGHT = $("#photo").height();
if(REAL_HEIGHT < 150)
{
//image not loaded.. try again in a quarter-second
setTimeout(adjust_photo_size, 250);
return;
}
}
var new_width = . . . ;
var new_height = . . . ;
$("#photo").width(Math.round(new_width));
$("#photo").height(Math.round(new_height));
}
});
Actualización : gracias por las sugerencias. Existe el riesgo de que el evento no se active si establezco una devolución de llamada para el evento de $("#photo").load
, por lo que he definido un evento onLoad directamente en la etiqueta de la imagen. Para el registro, aquí está el código que terminé yendo:
<img id="photo"
onload="photoLoaded();"
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Entonces en Javascript:
//This must be outside $() because it may get called first
var isPhotoLoaded = false;
function photoLoaded()
{
isPhotoLoaded = true;
}
$(function()
{
//Hides scrollbars, so we can resize properly. Set with JS instead of
// CSS so that page doesn''t break with JS disabled.
$("body").css("overflow", "hidden");
var REAL_WIDTH = -1;
var REAL_HEIGHT = -1;
$(window).resize(adjust_photo_size);
adjust_photo_size();
function adjust_photo_size()
{
if(!isPhotoLoaded)
{
//image not loaded.. try again in a quarter-second
setTimeout(adjust_photo_size, 250);
return;
}
else if(REAL_WIDTH < 0)
{
//first time in this function since photo loaded
REAL_WIDTH = $("#photo").width();
REAL_HEIGHT = $("#photo").height();
}
var new_width = . . . ;
var new_height = . . . ;
$("#photo").width(Math.round(new_width));
$("#photo").height(Math.round(new_height));
}
});
¿Algún comentario sobre este?
...
doShow = function(){
if($(''#img_id'').attr(''complete'')){
alert(''Image is loaded!'');
} else {
window.setTimeout(''doShow()'',100);
}
};
$(''#img_id'').attr(''src'',''image.jpg'');
doShow();
...
Parece que funciona en todas partes ...
Acabo de crear una función jQuery para cargar una imagen usando jQuerys Objeto diferido, lo que hace que sea muy fácil reaccionar ante un evento de carga / error:
$.fn.extend({
loadImg: function(url, timeout) {
// init deferred object
var defer = $.Deferred(),
$img = this,
img = $img.get(0),
timer = null;
// define load and error events BEFORE setting the src
// otherwise IE might fire the event before listening to it
$img.load(function(e) {
var that = this;
// defer this check in order to let IE catch the right image size
window.setTimeout(function() {
// make sure the width and height are > 0
((that.width > 0 && that.height > 0) ?
defer.resolveWith :
defer.rejectWith)($img);
}, 1);
}).error(function(e) {
defer.rejectWith($img);
});
// start loading the image
img.src = url;
// check if it''s already in the cache
if (img.complete) {
defer.resolveWith($img);
} else if (0 !== timeout) {
// add a timeout, by default 15 seconds
timer = window.setTimeout(function() {
defer.rejectWith($img);
}, timeout || 15000);
}
// return the promise of the deferred object
return defer.promise().always(function() {
// stop the timeout timer
window.clearTimeout(timer);
timer = null;
// unbind the load and error event
this.off("load error");
});
}
});
Uso:
var image = $(''<img />'').loadImg(''http://www.google.com/intl/en_com/images/srpr/logo3w.png'')
.done(function() {
alert(''image loaded'');
$(''body'').append(this);
}).fail(function(){
alert(''image failed'');
});
Véalo trabajando en: http://jsfiddle.net/roberkules/AdWZj/
Agregue un detector de eventos o haga que la imagen se anuncie con onload. Luego, calcula las dimensiones desde allí.
<img id="photo"
onload=''loaded(this.id)''
src="a_really_big_file.jpg"
alt="this is some alt text"
title="this is some title text" />
Desarrollamos una página donde cargaba varias imágenes y luego realizaba otras funciones solo después de cargar la imagen. Era un sitio ocupado que generaba mucho tráfico. Parece que el siguiente script simple funcionó en prácticamente todos los navegadores:
$(elem).onload = function() {
doSomething();
}
PERO ESTO ES UN PROBLEMA POTENCIAL PARA IE9!
El ÚNICO navegador en el que informamos problemas es IE9. ¿No estamos sorprendidos? Parece que la mejor manera de resolver el problema es no asignar un src a la imagen hasta DESPUÉS de que se haya definido la función de carga, así:
$(elem).onload = function() {
doSomething();
}
$(elem).attr(''src'',''theimage.png'');
Parece que IE 9 a veces no lanzará el evento de onload
por la razón que sea. Otras soluciones en esta página (como la de Evan Carroll, por ejemplo) todavía no funcionaban. Lógicamente, eso verificaba si el estado de carga ya era exitoso y activaba la función y si no era así, configuraba el controlador de onload, pero incluso cuando lo hacía, demostramos al probar que la imagen podía cargar entre esas dos líneas de js. que aparece no cargado en la primera línea y luego se carga antes de que se configure el controlador de carga.
Descubrimos que la mejor manera de obtener lo que desea es no definir la función de la imagen hasta que haya configurado el desencadenante del evento onload
.
Acabamos de dejar de soportar IE8 recientemente, así que no puedo hablar de versiones anteriores a IE9, de lo contrario, de todos los otros navegadores que se usaron en el sitio: IE10 y 11, así como Firefox, Chrome, Opera, Safari y lo que sea la gente del navegador móvil usaba: configurar el src
antes de asignar el controlador de onload
ni siquiera era un problema.
Desea hacer lo que dijo Allain, sin embargo, tenga en cuenta que a veces la imagen se carga antes del dom listo, lo que significa que su controlador de carga no se disparará. La mejor manera es hacer lo que dice Allain, pero configure el src de la imagen con javascript después de conectar el dispositivo de carga. De esta manera puedes garantizar que se dispare.
En términos de accesibilidad, ¿su sitio aún funcionará para personas sin javascript? Es posible que desee darle a la etiqueta img el código correcto, adjuntar el controlador dom ready para ejecutar su js: borrar la imagen src (darle un valor fijo y alto con css para evitar que la página parpadee), luego configure su controlador de carga img, luego reinicie el src al archivo correcto. De esta manera cubre todas las bases :)
Encontré que esto funcionó para mí
document.querySelector("img").addEventListener("load", function() { alert(''onload!''); });
El crédito es total para Frank Schwieterman, quien comentó la respuesta aceptada. Tuve que poner esto aquí, es demasiado valioso ...
Esta función verifica si una imagen se carga en función de tener dimensiones medibles. Esta técnica es útil si su script se está ejecutando después de que algunas de las imágenes ya se hayan cargado.
imageLoaded = function(node) {
var w = ''undefined'' != typeof node.clientWidth ? node.clientWidth : node.offsetWidth;
var h = ''undefined'' != typeof node.clientHeight ? node.clientHeight : node.offsetHeight;
return w+h > 0 ? true : false;
};
Hay un complemento de jQuery llamado "imagesLoaded" que proporciona un método compatible con varios navegadores para verificar si las imágenes de un elemento se han cargado.
Sitio: https://github.com/desandro/imagesloaded/
Uso para un contenedor que tiene muchas imágenes adentro:
$(''container'').imagesLoaded(function(){
console.log("I loaded!");
})
El plugin es genial:
- funciona para verificar un contenedor con muchas imágenes dentro
- funciona para comprobar un img para ver si se ha cargado
La respuesta correcta es usar event.special.load
Es posible que el evento de carga no se active si la imagen se carga desde el caché del navegador. Para tener en cuenta esta posibilidad, podemos usar un evento de carga especial que se dispara inmediatamente si la imagen está lista. event.special.load está actualmente disponible como un complemento.
Por los documentos en .load()
Pruebe algo como:
$("#photo").load(function() {
alert("Hello from Image");
});
Según uno de los comentarios recientes a su pregunta original
$(function() {
$(window).resize(adjust_photo_size);
adjust_photo_size();
function adjust_photo_size() {
if (!$("#photo").get(0).complete) {
$("#photo").load(function() {
adjust_photo_size();
});
} else {
...
}
});
Advertencia Esta respuesta podría causar un ciclo serio en ie8 y menor, porque img.complete no siempre está configurado correctamente por el navegador. Si debe admitir ie8, use una bandera para recordar que la imagen está cargada.
Usando el almacén de datos jquery puede definir un estado ''cargado''.
<img id="myimage" onload="$(this).data(''loaded'', ''loaded'');" src="lolcats.jpg" />
Luego, en otro lugar puedes hacer:
if ($(''#myimage'').data(''loaded'')) {
// loaded, so do stuff
}