Vérifier si une image est chargée (pas d'erreurs) dans JavaScript

J'utilise JavaScript avec la bibliothèque jQuery pour manipuler les vignettes d'image contenues dans une liste non ordonnée. Quand l'image est chargée, elle fait une chose, quand une erreur se produit, elle fait autre chose. J'utilise les méthodes load() et error () comme events. après ces événements je vérifie l'élément image DOM pour le .complet pour s'assurer que l'image n'était pas déjà chargée avant que jQuery puisse enregistrer les événements.

Il fonctionne correctement sauf quand une erreur se produit avant que jQuery puisse enregistrer les événements. la seule solution à laquelle je peux penser est d'utiliser l'attribut img onerror pour stocker un" flag "quelque part globalement (ou sur le noeud c'est soi) qui dit qu'il a échoué afin que jQuery puisse vérifier que" store/node " lors de la vérification .compléter.

Quelqu'un a une meilleure solution?

Edit: en Gras les points principaux et les plus en détail ci-dessous: Je vérifie si une image est complet (chargé) après que j'ai ajouté un événement de charge et d'erreur sur l'image. De cette façon, si l'image a été chargée avant que les événements ne soient enregistrés, je le saurai toujours. si l'image n'est pas chargée après les événements, les événements s'en chargeront quand ils le feront. Le problème avec ceci est que je peux facilement vérifier si une image est déjà chargée, mais Je ne peux pas dire si une erreur s'est produite à la place.

189
demandé sur William 2009-12-30 03:58:21

14 réponses

une autre option consiste à déclencher les événements onload et/ou onerror en créant un élément d'image en mémoire et en définissant son attribut src à l'attribut src original de l'image originale. Voici un exemple de ce que je veux dire:

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

Espérons que cette aide!

223
répondu Xavi 2015-07-16 12:09:24

vérifier les propriétés complete et naturalWidth , dans cet ordre.

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
répondu SLaks 2017-10-11 20:51:09

basé sur ma compréhension de la spécification HTML du W3C pour img élément , vous devriez être en mesure de faire ceci en utilisant une combinaison des attributs complete et naturalHeight comme ceci:

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

de la spécification pour l ' complete attribut:

l'attribut IDL complete must retourne true si une des conditions suivantes conditions est vraie:

  • l'attribut src est omis.
  • la tâche finale qui est mise en file d'attente par la source de la tâche de réseau une fois que la ressource a été récupérée a été mise en file d'attente.
  • l'élément img est entièrement disponible.
  • l'élément img est cassé.

sinon, l'attribut doit retourner false.

donc essentiellement, complete retourne true si l'image a fini de charger, ou n'a pas réussi à charger. Puisque nous voulons seulement le cas où l'image chargée avec succès nous devons vérifier l'attribut nauturalHeight ainsi:

les attributs IDL naturalWidth et naturalHeight doivent renvoyer le largeur et hauteur intrinsèques de l'image, en pixels CSS, si l'image est disponible, ou 0 sinon.

et available est défini comme suit:

Une img est toujours dans l'un des états suivants:

  • indisponible - l'agent utilisateur n'a pas obtenu de données d'image.
  • partiellement disponible - l'agent utilisateur a obtenu certaines des données d'image.
  • entièrement disponible - l'agent utilisateur a obtenu toutes les données d'image et au moins les dimensions d'image sont disponibles.
  • cassé - l'agent utilisateur a obtenu toutes les données d'image qu'il peut, mais il ne peut même pas décoder l'image assez pour obtenir l'image dimensions (par exemple l'image est corrompue, ou le format n'est pas pris en charge, ou on n'a pas pu être obtenu).

Lorsqu'un élément img est partiellement disponible ou partiellement disponible l'complètement à la disposition de l'état, il est dit d'être disponible.

donc si l'image est" broken "(non chargée), alors elle sera dans l'état broken, pas dans l'état disponible, donc naturalHeight sera 0.

par conséquent, la vérification de imgElement.complete && imgElement.naturalHeight !== 0 devrait nous indiquer si l'image a été chargée avec succès.

Vous pouvez en savoir plus sur ceci dans la spécification HTML du W3C pour img l'élément , ou sur MDN .

47
répondu Ajedi32 2016-10-25 14:20:44

j'ai essayé beaucoup de façons différentes et cette façon est la seule qui a fonctionné pour moi

//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');
});

vous pouvez également ajouter une fonction de rappel déclenchée une fois que toutes les images sont chargées dans le DOM et prêtes. Cela s'applique également aux images dynamiquement ajoutées. http://jsfiddle.net/kalmarsh80/nrAPk /

16
répondu Kal 2015-09-04 22:44:38
11
répondu Josh Harrison 2017-05-23 12:34:39

détecteur de réseau en temps réel-vérifier l'état du réseau sans rafraîchir la page: (ce n'est pas jquery, mais testé et fonctionne à 100%: (testé sur Firefox v25.0))

Code:

<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 la connexion est perdue, appuyez simplement sur le bouton "Again".

mise à Jour 1: Auto détecter sans rafraîchir la page:

<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
répondu Jenei Tamás 2013-10-16 15:11:04

récupérer des informations à partir des éléments d'image sur la page

Test sur Chrome et Firefox

Working jsFiddle (ouvrez votre console pour voir le résultat)

$('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);

});

Note: j'ai utilisé jQuery , j'ai pensé que cela pouvait être obtenu sur javascript complet

- je trouver de bonnes informations ici OpenClassRoom --> c'est un français forum

3
répondu Julha 2016-04-20 00:52:27

C'est ainsi que j'ai fait fonctionner cross browser en utilisant une combinaison des méthodes ci-dessus (j'avais aussi besoin d'insérer des images dynamiquement dans le 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');
    }
});

Note: vous devrez fournir un État booléen valide pour la variable isIE.

2
répondu Justin Vincent 2013-03-30 19:20:12

après avoir lu les solutions intéressantes sur cette page, j'ai créé une solution facile à l'utilisation fortement influencée par SLaks' et le post de Noyo qui semble travailler sur des versions assez récentes (comme l'écriture) de Chrome, IE, Firefox, Safari, et Opera (tous sur Windows). De plus, cela a fonctionné sur un émulateur iPhone/iPad que j'ai utilisé.

une différence majeure entre cette solution et SLaks et Noyo's post est que cette solution vérifie principalement la largeur et la hauteur naturelles propriété. J'ai trouvé que dans les versions de navigateur actuelles, ces deux propriétés semblent fournir les résultats les plus utiles et cohérents.

ce code renvoie TRUE lorsqu'une image a été chargée complètement et avec succès. Il retourne FALSE quand une image n'a pas encore été chargée ou ne l'a pas été.

une chose dont vous devez être conscient est que cette fonction retournera également FALSE si l'image est une image 0x0 pixel. Mais ces images sont assez rare, et je ne peux pas penser à un très utile si vous voulez vérifier pour voir si un 0 x 0 pixels de l'image a encore chargé :)

tout d'abord, nous attachons une nouvelle fonction appelée "isLoaded" au prototype HTMLImageElement, afin que cette fonction puisse être utilisée sur n'importe quel élément d'image.

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;

};

Ensuite, chaque fois que nous avons besoin de vérifier l'état de chargement de l'image, nous appelons simplement la fonction "isLoaded".

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

Per giorgian commentaire sur le post de SLaks et de Noyo, cette solution ne peut probablement être utilisée que comme un contrôle unique sur Safari Mobile si vous prévoyez de changer L'attribut SRC. Mais vous pouvez contourner cela en créant un élément image avec un nouvel attribut SRC au lieu de changer L'attribut SRC sur un élément image existant.

2
répondu data-dan 2015-07-28 17:53:58

si je comprends bien .la propriété complète n'est pas standard. Il ne peut pas être universelle... Je remarque qu'il semble fonctionner différemment dans Firefox versets IE. Je charge un certain nombre d'images en javascript, puis je vérifie si elles sont complètes. Dans Firefox, cela semble fonctionner très bien. Dans IE, ce n'est pas parce que les images semblent charger sur un autre thread. Il ne fonctionne que si je mets un délai entre mon affectation à l'image.src et quand j'ai vérifier l'image.complète la propriété.

à l'Aide de image.onload et de l'image.onerror ne fonctionne pas pour moi non plus, parce que j'ai besoin de passer un paramètre pour savoir de quelle image je parle quand la fonction est appelée. Toute façon de faire cela semble échouer parce qu'il semble effectivement passer la même fonction, pas des instances différentes de la même fonction. Donc la valeur que je passe dedans pour identifier l'image finit toujours par être la dernière valeur dans la boucle. Je ne vois pas de moyen de contourner ce problème.

sur Safari et Chrome, Je vois l'image.complétez true et le paramètre naturalWidth même si la console d'erreur affiche un 404 pour cette image... et j'ai intentionnellement enlevé cette image pour tester ça. Mais ce qui précède fonctionne bien pour Firefox et IE.

1
répondu user1018645 2011-10-28 18:07:12

en utilisant ce code JavaScript vous pouvez vérifier que l'image est chargée avec succès ou non.

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

essayez ceci

0
répondu Ajay Gupta 2015-12-04 11:53:43

j'ai eu beaucoup de problèmes avec la charge complète d'une image et L'Evenlistener.

quoi que j'aie essayé, les résultats n'étaient pas fiables.

mais j'ai trouvé la solution. Techniquement, ce n'est pas un beau film, mais maintenant je n'ai jamais eu de charge d'image ratée.

ce que j'ai fait:

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

au lieu de charger l'image Une fois, je le charge juste une deuxième fois directement après la première fois et les deux exécuter auge le gestionnaire d'événements.

Tous mes maux de tête ont disparu!


Par la façon dont: Vous les gars de stackoverflow m'avez déjà aidé plus de cent fois. Pour cela, un très grand Merci à vous!

0
répondu Scoobeedo Cool 2017-02-27 06:36:27

cet extrait de code m'a aidé à corriger les problèmes de mise en cache du navigateur:

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

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

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

lorsque le cache du navigateur est désactivé, seul ce code ne fonctionne pas:

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

pour le faire fonctionner vous devez ajouter:

.each(function() {
     if($(this).prop('complete')) $(this).load();
});
0
répondu Frank 2017-12-15 12:52:05
var isImgLoaded = function(imgSelector){
  return $(imgSelector).prop("complete") && $(imgSelector).prop("naturalWidth") !== 0;
}

// Ou en tant Que Plugin

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

// $(".myImage").isLoaded() 
0
répondu KhaledDev 2018-03-25 08:16:25