259 votes

Vérifier si une image est chargée (sans erreur) avec jQuery

J'utilise JavaScript avec la bibliothèque jQuery pour manipuler des vignettes d'images contenues dans une liste non ordonnée. Lorsque l'image est chargée, elle fait une chose, lorsqu'une erreur se produit, elle fait autre chose. J'utilise jQuery load() y error() comme des événements. Après ces événements, je vérifie l'élément DOM de l'image pour le .complete afin de m'assurer que l'image n'était pas déjà chargée avant que jQuery puisse enregistrer les événements.

Il fonctionne correctement, sauf lorsqu'une erreur se produit avant que jQuery puisse enregistrer les événements. La seule solution qui me vient à l'esprit est d'utiliser la fonction img. onerror pour stocker un "drapeau" quelque part dans le monde (ou sur le nœud lui-même) qui indique que l'opération a échoué, de sorte que jQuery puisse vérifier ce "magasin/nœud" lors de la vérification de .complete.

Quelqu'un a-t-il une meilleure solution ?

Edition : Les points principaux ont été mis en gras et des détails supplémentaires ont été ajoutés ci-dessous : Je vérifie si une image est complète (c'est-à-dire chargée) APRÈS avoir ajouté un événement de chargement et d'erreur sur l'image. De cette façon, si l'image a été chargée avant l'enregistrement des événements, je le saurai quand même. Si l'image n'est pas chargée après les événements, ces derniers s'en chargeront quand elle le sera. Le problème, c'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.

0 votes

Quand enregistrez-vous les événements jQuery ? Peut-être que quelques codes vous aideront :)

0 votes

Il y a beaucoup de code, ce que j'ai dit ci-dessus est juste une version très simple de ce que je fais. J'appelle les événements après que le DOM soit chargé, une méthode est appelée pour ajouter des événements aux vignettes.

279voto

SLaks Points 391154

Vérifiez le complete y naturalWidth les propriétés, 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;
}

1 votes

Intéressant, je regardais ce post plus tôt et je n'avais pas réalisé qu'ils faisaient ! complet pour IE car naturalWidth n'est pas défini dans IE. Je vais le vérifier maintenant.

0 votes

Je pense que j'aurais dû mieux m'expliquer dans ma question principale. J'appelle cette méthode après avoir ajouté les événements load,error pour que je sache si une erreur s'est déjà produite. Cette méthode renvoie false même si une méthode est toujours en train de "charger" et qu'elle n'a pas d'erreur. J'ai besoin de quelque chose pour vérifier s'il y a eu une erreur, si le chargement est toujours en cours / complet, il devrait retourner vrai. Merci pour la réponse.

0 votes

Mis à jour, faites-moi savoir si vous voulez plus de détails. Merci pour votre aide

272voto

Xavi Points 9768

Une autre option consiste à déclencher le onload et/ou onerror en créant un élément d'image dans la mémoire et en définissant son src à l'attribut original src 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"))
;

J'espère que cela vous aidera !

0 votes

Hmm cela semble fonctionner, et après quelques tests cela ne semble pas nuire au chargement de l'image non plus. Merci !

30 votes

Ça n'a pas l'air de fonctionner aussi bien que je l'espérais. Dans Google Chrome, il semble avoir des problèmes lorsque l'image est déjà dans le cache. Il ne déclenche pas la méthode load() :(

4 votes

Ugg, tu as raison. Chrome est définitivement le navigateur le plus ennuyeux à développer. Je pense avoir trouvé un moyen de contourner le problème : définir la source de l'image sur "" puis revenir à la source originale. Je vais mettre à jour ma réponse.

26voto

Kal Points 113

J'ai essayé de nombreuses 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 ajoutées dynamiquement. http://jsfiddle.net/kalmarsh80/nrAPk/

1 votes

J'ai testé les lectures intéressantes ci-dessus et elles échouent entre les tests en cache/hors cache sur une poignée de navigateurs courants. Cette réponse est similaire à une autre mais c'est celle que j'ai implémentée et testée à l'instant, je peux confirmer qu'elle fonctionne sur : EdgeWin10, IE11Win8.1, Win7IE10, Win7IE9, iOS 10.2 Chrome, iOS 10.2 Safari, mac os 10.12 Chrome, mac os 10.12 Safari, mac os 10.12 Firefox, Google Pixel 7.1, Samsung S5 Android 4.4. N'oubliez pas d'utiliser aussi addEventListener/removeEventListener :D

0 votes

Notez que cela charge techniquement otro copie de l'image et utilise l'événement de chargement de ce proxy comme événement pour l'image. Cela ne permet évidemment pas de faire correspondre l'image originale avec la même URL si les en-têtes HTTP n'autorisent pas le partage du résultat mis en cache !

14voto

Zougen Moriver Points 2306

Utilice imagesLoaded bibliothèque javascript .

Utilisable avec le simple Javascript et comme plugin jQuery.

Caractéristiques :

Ressources

0 votes

Ceci a parfaitement fonctionné pour moi. function checkImages(imgs) { $(imgs).each(function() { $(imgs).imagesLoaded() .progress(function(instance, image) { if(image.isLoaded == false) { console.log(image.img.src + ' could not be found.') ; image.img.src = "/templates/img/no-image.jpg" ; } ; } ; } ; } ; } ; }. }) ; }) ; }

2 votes

Il semble y avoir une tonne de problèmes ouverts et de bogues majeurs, et le développeur ne semble pas faire grand-chose pour les rattraper. pour l'instant, il est totalement inutilisable dans un environnement de production.

3 votes

@vsync Avez-vous lu certains des problèmes ouverts ? Il répond à la quasi-totalité d'entre eux, et la plupart semblent être des cas limites non reproductibles que peu d'autres personnes rencontrent. Je n'ai jamais eu de problème avec lui en production.

2voto

Justin Vincent Points 554

Voici comment j'ai réussi à le faire fonctionner sur plusieurs navigateurs en utilisant une combinaison des méthodes ci-dessus (j'ai également dû insérer des images de façon dynamique dans le domaine) :

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

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X