Comprobar si una imagen está cargada (sin errores) en JavaScript


Estoy usando JavaScript con la biblioteca jQuery para manipular miniaturas de imágenes contenidas en una lista desordenada. Cuando se carga la imagen hace una cosa, cuando ocurre un error hace otra cosa. Estoy usando los métodos load() y error() de jQuery como eventos. Después de estos eventos compruebo el elemento DOM de la imagen para el.complete para asegurarse de que la imagen no estaba ya cargada antes de que jQuery pudiera registrar los eventos.

Funciona correctamente excepto cuando se produce un error antes jQuery puede registrar los eventos. La única solución que se me ocurre es usar el atributo img onerror para almacenar un "flag" en algún lugar globalmente (o en el nodo que es uno mismo) que dice que falló para que jQuery pueda verificar ese "store/node" al verificar .completo.

Alguien tiene una solución mejor?

Editar: Puntos principales en negrita y detalles adicionales añadidos abajo: Estoy comprobando si una imagen está completa (también conocida como loaded) DESPUÉS de agregar un evento de carga y error en la imagen. De esa manera, si la imagen fue cargado antes de que los eventos fueran registrados, todavía lo sabré. Si la imagen no se carga después de los eventos, entonces los eventos se encargarán de ella cuando lo haga. El problema con esto es que puedo comprobar fácilmente si una imagen ya está cargada, pero No puedo decir si se produjo un error en su lugar.

Author: William, 2009-12-30

14 answers

Otra opción es activar los eventos onload y/o onerror creando un elemento de imagen en memoria y estableciendo su atributo src al atributo src original de la imagen original. He aquí un ejemplo de lo que quiero decir:

$("<img/>")
    .on('load', function() { console.log("image loaded correctly"); })
    .on('error', function() { console.log("error loading image"); })
    .attr("src", $(originalImage).attr("src"))
;

Espero que esto ayude!

 223
Author: Xavi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-16 12:09:24

Compruebe las propiedades complete y naturalWidth, en ese orden.

Https://stereochro.me/ideas/detecting-broken-images-js

function IsImageOk(img) {
    // During the onload event, IE correctly identifies any images that
    // weren’t downloaded as not complete. Others should too. Gecko-based
    // browsers act like NS4 in that they report this incorrectly.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth and
    // naturalHeight. These give the true size of the image. If it failed
    // to load, either of these should be zero.
    if (img.naturalWidth === 0) {
        return false;
    }

    // No other way of checking: assume it’s ok.
    return true;
}
 199
Author: SLaks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-11 20:51:09

Basado en mi comprensión de la especificación HTML del W3C para el elemento img , debería poder hacer esto usando una combinación de complete y naturalHeight atributos, así:

function imgLoaded(imgElement) {
  return imgElement.complete && imgElement.naturalHeight !== 0;
}

De la especificación para el complete atributo:

El atributo IDL complete debe devolver true si cualquiera de los siguientes las condiciones son ciertas:

  • Se omite el atributo src.
  • La tarea final que está en cola por el origen de la tarea de red una vez que se ha obtenido el recurso se ha puesto en cola.
  • El elemento img está completamente disponible.
  • El elemento img está roto.

De lo contrario, el atributo debe devolver false.

Así que esencialmente, complete devuelve true si la imagen ha terminado de cargarse o no se ha cargado. Dado que solo queremos el caso en el que la imagen se cargó con éxito, tenemos que comprobar el nauturalHeight atributo también:

Los atributos IDL naturalWidth y naturalHeight deben devolver anchura y altura intrínsecas de la imagen, en píxeles CSS, si la imagen está disponible, o bien 0.

Y available se define como:

Un img está siempre en uno de los siguientes estados:

  • No disponible - El agente de usuario no ha obtenido ningún dato de imagen.
  • Parcialmente disponible - El agente de usuario ha obtenido algunos de los datos de la imagen.
  • Completamente disponible - El agente de usuario ha obtenido todos los datos de la imagen y al menos las dimensiones de la imagen están disponibles.
  • Roto - El agente de usuario ha obtenido todos los datos de imagen que puede, pero ni siquiera puede decodificar la imagen lo suficiente como para obtener la imagen dimensiones (por ejemplo, la imagen está dañada o el formato no compatible, o no se pudo obtener ningún dato).

Cuando un elemento img está en el estado parcialmente disponible o en el estado completamente disponible, se dice que está disponible.

Así que si la imagen está "rota" (no se pudo cargar), entonces estará en el estado roto, no el estado disponible, por lo que naturalHeight será 0.

Por lo tanto, la comprobación de imgElement.complete && imgElement.naturalHeight !== 0 debe decirnos si la imagen se ha cargado correctamente.

Puede leer más sobre esto en la especificación HTML del W3C para el elemento img , o en MDN.

 47
Author: Ajedi32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-25 14:20:44

Probé muchas maneras diferentes y esta es la única que funcionó para mí

//check all images on the page
$('img').each(function(){
    var img = new Image();
    img.onload = function() {
        console.log($(this).attr('src') + ' - done!');
    }
    img.src = $(this).attr('src');
});

También podría agregar una función de devolución de llamada activada una vez que todas las imágenes se carguen en el DOM y estén listas. Esto también se aplica a las imágenes añadidas dinámicamente. http://jsfiddle.net/kalmarsh80/nrAPk /

 16
Author: Kal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-04 22:44:38
 11
Author: Josh Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:39

Realtime network detector-comprobar el estado de la red sin actualizar la página: (no es jquery, pero probado, y 100% funciona: (probado en Firefox v25.0))

Código:

<script>
 function ImgLoad(myobj){
   var randomNum = Math.round(Math.random() * 10000);
   var oImg=new Image;
   oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
   oImg.onload=function(){alert('Image succesfully loaded!')}
   oImg.onerror=function(){alert('No network connection or image is not available.')}
}
window.onload=ImgLoad();
</script>

<button id="reloadbtn" onclick="ImgLoad();">Again!</button>

Si se pierde la conexión, simplemente presione el botón De nuevo.

Actualización 1: Detección automática sin actualizar la página:

<script>
     function ImgLoad(myobj){
       var randomNum = Math.round(Math.random() * 10000);
       var oImg=new Image;
       oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
       oImg.onload=function(){networkstatus_div.innerHTML="";}
       oImg.onerror=function(){networkstatus_div.innerHTML="Service is not available. Please check your Internet connection!";}
}

networkchecker = window.setInterval(function(){window.onload=ImgLoad()},1000);
</script>

<div id="networkstatus_div"></div>
 3
Author: Jenei Tamás,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-16 15:11:04

Recuperar información de elementos de imagen en la página
Prueba de trabajo en Chrome y Firefox
Trabajando jsFiddle (abre tu consola para ver el resultado)

$('img').each(function(){ // selecting all image element on the page

    var img = new Image($(this)); // creating image element

    img.onload = function() { // trigger if the image was loaded
        console.log($(this).attr('src') + ' - done!');
    }

    img.onerror = function() { // trigger if the image wasn't loaded
        console.log($(this).attr('src') + ' - error!');
    }

    img.onAbort = function() { // trigger if the image load was abort
        console.log($(this).attr('src') + ' - abort!');
    }

    img.src = $(this).attr('src'); // pass src to image object

    // log image attributes
    console.log(img.src);
    console.log(img.width);
    console.log(img.height);
    console.log(img.complete);

});

Nota: Usé jQuery , pensé que esto se puede lograr en javascript completo

Encuentro buena información aquí OpenClassRoom this > este es un foro francés

 3
Author: Julha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-20 00:52:27

Así es como conseguí que funcionara cross browser usando una combinación de los métodos anteriores (también necesitaba insertar imágenes dinámicamente en el dom):

$('#domTarget').html('<img src="" />');

var url = '/some/image/path.png';

$('#domTarget img').load(function(){}).attr('src', url).error(function() {
    if ( isIE ) {
       var thisImg = this;
       setTimeout(function() {
          if ( ! thisImg.complete ) {
             $(thisImg).attr('src', '/web/css/img/picture-broken-url.png');
          }
       },250);
    } else {
       $(this).attr('src', '/web/css/img/picture-broken-url.png');
    }
});

Nota: Deberá proporcionar un estado booleano válido para la variable ie.

 2
Author: Justin Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-30 19:20:12

Después de leer las soluciones interesantes en esta página, he creado una solución fácil de usar altamente influenciado por SLaks' y Noyo's post que parece estar trabajando en versiones bastante recientes (como de la escritura) de Chrome, IE, Firefox, Safari, y Opera (todo en Windows). Además, funcionó en un emulador de iPhone/iPad que utilicé.

Una diferencia importante entre esta solución y SLaks y el post de Noyo es que esta solución comprueba principalmente las propiedades naturalWidth y naturalHeight. He encontrado que en las versiones actuales del navegador, esas dos propiedades parecen proporcionar los resultados más útiles y consistentes.

Este código devuelve TRUE cuando una imagen se ha cargado completamente Y con éxito. Devuelve FALSE cuando una imagen no se ha cargado completamente O no se ha cargado.

Una cosa que debe tener en cuenta es que esta función también devolverá FALSE si la imagen es una imagen de 0x0 píxeles. Pero esas imágenes son muy poco comunes, y no puedo pensar en un caso muy útil donde usted me gustaría comprobar si una imagen de 0x0 píxeles se ha cargado todavía:)

Primero adjuntamos una nueva función llamada "IsLoaded" al prototipo de HTMLImageElement, para que la función se pueda usar en cualquier elemento de imagen.

HTMLImageElement.prototype.isLoaded = function() {

    // See if "naturalWidth" and "naturalHeight" properties are available.
    if (typeof this.naturalWidth == 'number' && typeof this.naturalHeight == 'number')
        return !(this.naturalWidth == 0 && this.naturalHeight == 0);

    // See if "complete" property is available.
    else if (typeof this.complete == 'boolean')
        return this.complete;

    // Fallback behavior: return TRUE.
    else
        return true;

};

Entonces, cada vez que necesitamos verificar el estado de carga de la imagen, solo llamamos a la función "IsLoaded".

if (someImgElement.isLoaded()) {
    // YAY! The image loaded
}
else {
    // Image has not loaded yet
}

Según el comentario de giorgian en SLaks ' y el post de Noyo, esta solución probablemente solo se puede usar como una comprobación de una sola vez en Safari Mobile si planea cambiando el atributo SRC. Pero puede evitar eso creando un elemento de imagen con un nuevo atributo SRC en lugar de cambiar el atributo SRC en un elemento de imagen existente.

 2
Author: data-dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-28 17:53:58

Según entiendo el.propiedad completa no es estándar. Puede que no sea universal... Me doy cuenta de que parece funcionar de manera diferente en Firefox versos IE. Estoy cargando una serie de imágenes en javascript y luego comprobando si están completas. En Firefox, esto parece funcionar muy bien. En IE, no lo hace porque las imágenes parecen estar cargando en otro hilo. Funciona solo si pongo un retraso entre mi asignación a la imagen.src y cuando compruebo la imagen.propiedad completa.

Usando imagen.onload y imagen.onerror tampoco funciona para mí, porque necesito pasar un parámetro para saber de qué imagen estoy hablando cuando se llama a la función. Cualquier forma de hacer eso parece fallar porque en realidad parece pasar la misma función, no diferentes instancias de la misma función. Así que el valor que le paso para identificar la imagen siempre termina siendo el último valor en el bucle. No se me ocurre ninguna solución a este problema.

En Safari y Chrome, estoy viendo la imagen.completo true y el conjunto naturalWidth incluso cuando la consola de error muestra un 404 para esa imagen... y quité intencionalmente esa imagen para probar esto. Pero lo anterior funciona bien para Firefox e IE.

 1
Author: user1018645,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-28 18:07:12

Usando este código JavaScript puede comprobar que la imagen se ha cargado correctamente o no.

document.onready = function(e) {
        var imageobj = new Image();
        imageobj.src = document.getElementById('img-id').src;
        if(!imageobj.complete){ 
            alert(imageobj.src+"  -  Not Found");
        }
}

Prueba esto

 0
Author: Ajay Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-04 11:53:43

Tuve muchos problemas con la carga completa de una imagen y el EventListener.

Lo que probé, los resultados no fueron confiables.

Pero entonces encontré la solución. Técnicamente no es una buena, pero ahora nunca tuve una carga de imagen fallida.

Lo que hice:

                    document.getElementById(currentImgID).addEventListener("load", loadListener1);
                    document.getElementById(currentImgID).addEventListener("load", loadListener2);

                function loadListener1()
                    {
                    // Load again
                    }

                function loadListener2()
                {
                    var btn = document.getElementById("addForm_WithImage"); btn.disabled = false;
                    alert("Image loaded");
                }

En lugar de cargar la imagen una vez, solo la cargo una segunda vez directamente después de la primera vez y ambos corren a través del eventhandler.

Todos mis dolores de cabeza se han ido!


Por manera: Ustedes de Stackoverflow ya me ayudaron más de cien veces. Por esto un gran Gracias!

 0
Author: Scoobeedo Cool,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-27 06:36:27

Este fragmento de código me ayudó a solucionar los problemas de caché del navegador:

$("#my_image").on('load', function() {

    console.log("image loaded correctly"); 
}).each(function() {

     if($(this).prop('complete')) $(this).load();
});

Cuando la caché del navegador está desactivada, solo que este código no funciona:

$("#my_image").on('load', function() {
     console.log("image loaded correctly"); 
})

Para que funcione hay que añadir:

.each(function() {
     if($(this).prop('complete')) $(this).load();
});
 0
Author: Frank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-15 12:52:05
var isImgLoaded = function(imgSelector){
  return $(imgSelector).prop("complete") && $(imgSelector).prop("naturalWidth") !== 0;
}

/ / O Como Complemento

    $.fn.extend({
      isLoaded: function(){
        return this.prop("complete") && this.prop("naturalWidth") !== 0;
      }
    })

// $(".myImage").isLoaded() 
 0
Author: KhaledDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-25 08:16:25