Comment masquer silencieusement l'icône «Image non trouvée» lorsque l'image source src n'est pas trouvée


91

Savez-vous comment masquer l' icône classique "Image non trouvée" d'une page HTML rendue lorsqu'un fichier image n'est pas trouvé?

Une méthode de travail utilisant JavaScript / jQuery / CSS?


La réponse d'Andy est correcte, cependant, vous pouvez utiliser style.vsibility à la place. Si vous définissez la visibilité, l'élément garde toujours son espace sur votre document, donc aucun mouvement de document amusant.
Christian

Je ne vois pas l'intérêt. Vous n'êtes tout simplement pas censé essayer d'atteindre aucune ressource existante à partir de votre code html. Utiliser javascript pour masquer les ressources mal gérées me semble être une mauvaise solution.
Boris Delormas

1
@Kaaviar Vous manquez le point. Il y a beaucoup d'images hotlink cassées ici sur Stack Overflow en raison du fait que les images peuvent être disponibles au moment de la publication, mais indisponibles quelques mois plus tard. Ces images sont silencieusement et doucement masquées.
systempuntoout

1
@systempuntoout: Je ne sais pas pourquoi les deux sont traités différemment. J'ai testé une image cassée dans Firefox et Chrome, elle ne s'affiche pas dans Firefox mais elle apparaît comme cassée dans Chrome. Il est clair que c'est quelque chose que Firefox décide de lui-même, car il ne semble pas que les styles l'affectent. btw, excellent travail sur StackPrinter.
Andy E

2
@systempuntoout: J'ai trouvé un peu plus d'informations sur la façon dont Firefox fonctionne avec cela. Voir un violon mis à jour et la [pseudo-classe propriétaire, :-moz-broken] ( developer.mozilla.org/en/CSS/:-moz-broken ). Je me disais juste plus tôt qu'une pseudo classe serait utile pour styliser des images cassées.
Andy E

Réponses:


102

Vous pouvez utiliser l' onerrorévénement dans JavaScript pour agir lorsqu'une image ne parvient pas à se charger:

var img = document.getElementById("myImg");
img.onerror = function () { 
    this.style.display = "none";
}

Dans jQuery (depuis que vous l'avez demandé):

$("#myImg").error(function () { 
    $(this).hide(); 
});

Ou pour toutes les images:

$("img").error(function () { 
    $(this).hide();
    // or $(this).css({visibility:"hidden"}); 
});

Vous devez utiliser visibility: hiddenau lieu de .hide()si le fait de masquer les images peut modifier la mise en page. De nombreux sites sur le Web utilisent à la place une image "sans image" par défaut, pointant l' srcattribut vers cette image lorsque l'emplacement de l'image spécifié n'est pas disponible.


1
andy - quelle serait la solution «globale» à appliquer à TOUTES les images ?? Je pense que ce serait assez facile s'ils étaient tous dans la même division - je me suis simplement posé des questions sur TOUTES les images du document ...
jim tollan

@jAndy: J'en étais assez sûr, mais votre commentaire m'a fait revérifier. Un rapide Google a renvoyé cette page w3schools (désolé David, si vous lisez ceci) indiquant la prise en charge de plusieurs navigateurs.
Andy E

2
@jim: Si vous utilisez jQuery, vous pouvez appliquer l'événement à toutes les images. utilisez simplement le sélecteur de balises, par exemple $("img").error(function () { /*...*/ });.
Andy E

@Andy E: ça sonne bien, +1. La prochaine question intéressante serait, est " error" bornable avec live()ou delegate().
jAndy

3
visibilityserait mieux, car displaypeut casser la mise en page.
gblazex

114
<img onerror='this.style.display = "none"'>

Malheureusement, je ne peux pas utiliser cette solution car le contenu html est téléchargé à partir d'un site Web tiers via Json et je ne peux pas le modifier. Merci quand même.
systempuntoout

9
Génial, exactement ce dont j'avais besoin. Simple et discret, il s'inscrit dans un gabarit!
Max

Bien que déjà assez vieux, c'est génial! Existe-t-il également un moyen de masquer les balises <a> entourant mon image désormais masquée?
SJDS

9

J'ai légèrement modifié la solution suggérée par Gary Willoughby, car elle montre brièvement l'icône d'image cassée. Ma solution:

    <img src="..." style="display: none" onload="this.style.display=''">

Dans ma solution, l'image est masquée initialement et ne s'affiche que lorsqu'elle est chargée avec succès. Cela présente un inconvénient: les utilisateurs ne verront pas les images à moitié chargées. Et si l'utilisateur a désactivé JS, il ne verra jamais aucune image


1
... et les utilisateurs ne verront rien, si javascript est désactivé!
yckart

4
@yckart Eh bien, si les utilisateurs ont désactivé javascript, la plupart des applications Web utiles ne fonctionneront pas de toute façon ...
awe

<img src="..." onerror="this.style.display = 'none'"/>pourrait fonctionner mieux pour les cas de navigateur à moitié chargés et non js?

6

Pour masquer chaque erreur d'image, ajoutez simplement ce JavaScript en bas de votre page (juste avant la balise de fermeture du corps):

(function() {
    var allimgs = document.images;
    for (var i = 0; i < allimgs.length; i++) {
        allimgs[i].onerror = function() {
            this.style.visibility = "hidden"; // Other elements aren't affected. 
        }
    }
})();

C'est mon approche préférée car elle garantit à peu près que les événements onerror sont liés avant que les images ne se soient trompées et que vous n'avez pas à ajouter d'attributs onerror à chaque balise d'image. Assurez-vous de mettre ce code après toutes vos balises d'image mais avant tout autre javascript qui se trouve dans <body>, sinon un chargement JS externe bloquant peut provoquer une exécution après une erreur d'image.
galates

Celui-ci fonctionne pour moi, avec les conseils des galates, il faut que ce JS s'exécute avant tout ce qui pourrait le retarder.
Adamz

Cela répond à la question initiale, mais c'est un processus à sens unique. Pour rendre à nouveau visibles les images qui se chargent par la suite, ajoutez également un événement onload. allimgs [i] .onload = function () {this.style.visibility = "visible"; };
TRT 1968

5

Il est peut-être un peu tard pour répondre, mais voici ma tentative. Lorsque j'ai rencontré le même problème, je l'ai résolu en utilisant un div de la taille de l'image et en définissant background-image sur ce div. Si l'image n'est pas trouvée, le div est rendu transparent, donc tout est fait en silence sans code java-script.


4

Faire une recherche rapide sur la réponse d' Andy E , il n'est pas possible de live()lier error.

// won't work (chrome 5)
$('img').live('error', function(){
     $(this).css('visibility', 'hidden');
});

Alors tu dois aller comme

$('<img/>', {
  src:    'http://www.notarget.com/fake.jpg',
  error:  function(e){
    $(this).css('visibility', 'hidden');
  }
}).appendTo(document.body);

liant directement le error event handlerlors de la création d'un nouvel élément.


2
+1, la raison en est que l' événement DOM onerror ne bouillonne pas. live et déléguez le travail en plaçant le gestionnaire d'événements plus haut dans la hiérarchie DOM et en capturant l'événement au fur et à mesure qu'il bouillonne. Bien sûr, les développeurs de jQuery ont contourné ce problème pour certains événements tels que la mise au point et le flou
Andy E

@Andy E: Oui, ils ont déjà contourné cela, ce n'est peut-être pas la pire des idées pour faire une chose similaire error. Sonne comme un nice to havepour moi.
jAndy

3

J'ai trouvé une méthode astucieuse pour faire exactement cela, tout en étant toujours fonctionnel lors de l'utilisation de la ng-srcdirective dans Angular.js et autres ...

<img
  ng-src="{{myCtrl.myImageUrlThatWillDynamicallyChange}}" 
  onerror="this.src='data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='"
  />

c'est fondamentalement un GIF transparent le plus court (comme vu http://proger.i-forge.net/%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82% D0% B5% D1% 80 / [20121112]% 20Le% 20smallest% 20transparent% 20pixel.html )

bien sûr, ce gif pourrait être conservé dans une variable globale pour ne pas gâcher les modèles.

<script>
  window.fallbackGif = "..."
</script>

et utilise

<img
  ng-src="{{myCtrl.myImageUrlThatWillDynamicallyChange}}" 
  onerror="this.src=fallbackGif"
  />

etc.


0

Utilisez simplement un CSS simple

.AdminImageHolder {
display: inline-block;
min-width: 100px;
max-width: 100px;
min-height: 100px;
max-height: 100px;
background: url(img/100x100.png) no-repeat;
border: 1px solid #ccc;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.