Saisie d'une image par défaut au cas où l'attribut src d'un html <img> n'est pas valide?
268
Existe-t-il un moyen de rendre une image par défaut dans une <img>balise HTML , au cas où l' srcattribut n'est pas valide (en utilisant uniquement du HTML)? Sinon, quelle serait votre façon légère de contourner ce problème?
HTML n'a pas de solution de rechange pour les images cassées. Vous devez utiliser JavaScript pour rechercher des images cassées et modifier leur attribut src.
Blixt
2
@Blixt - Et si votre client est MS Outlook ou un autre lecteur EMAIL et que vous n'avez pas Javascript, et que l'option objet ne fonctionne pas ... Je suppose que la seule solution est alt / text
Xofo
Réponses:
319
Vous avez demandé une solution HTML uniquement ...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd"><htmllang="en"><head><title>Object Test</title><metahttp-equiv="Content-Type"content="text/html; charset=utf-8"></head><body><p><objectdata="http://stackoverflow.com/does-not-exist.png"type="image/png"><imgsrc="https://cdn.sstatic.net/Img/unified/sprites.svg?v=e5e58ae7df45"alt="Stack Overflow logo and icons and such"></object></p></body></html>
Puisque la première image n'existe pas, le repli (les sprites utilisés sur ce site Web *) s'affichera. Et si vous utilisez un très ancien navigateur qui ne prend pas en charge object, il ignorera cette balise et l'utilisera img. Voir le site Web de caniuse pour la compatibilité. Cet élément est largement pris en charge par tous les navigateurs d'IE6 +.
* Sauf si l'URL de l'image a changé (à nouveau), auquel cas vous verrez probablement le texte alternatif.
Cela a fonctionné pour moi dans IE8 après avoir mis la DTD pour HTML 4.01.
Patrick McElhaney
Cela ne fonctionne pas si l'image non existante est X-Frame-Optionsdéfinie sur SAMEORIGINou un paramètre plus permissif.
Attila O.
Cela fonctionne mais si le lien dans object.data n'est pas fiable, il peut charger toutes sortes de choses ...
Michael_Scharf
1
L'élément «img» ne peut pas être imbriqué dans l'élément «objet».
Matheus Miranda
2
@Matheus Bien sûr que c'est possible. En HTML4, l'objet peut contenir du contenu de flux (presque tout, y compris img), et en HTML5 il est transparent, ce qui signifie qu'il peut contenir n'importe quel HTML5 valide.
Patrick McElhaney
318
Cela fonctionne bien pour moi. Peut-être que vous voulez utiliser JQuery pour accrocher l'événement.
Mise à jour: solution CSS uniquement
J'ai récemment vu Vitaly Friedman démo une excellente solution CSS que je ne connaissais pas. L'idée est d'appliquer la contentpropriété à l'image cassée. Normalement :afterou :beforene s'appliquent pas aux images, mais lorsqu'elles sont cassées, elles sont appliquées.
Comme le montre le violon, l'image cassée elle-même n'est pas supprimée, mais cela résoudra probablement le problème dans la plupart des cas sans JS ni gouttes de CSS. Si vous devez appliquer différentes images à différents endroits, différenciez-les simplement avec une classe:.my-special-case img:before { ...
BTW, si error.jpg n'existe pas, cela provoque une boucle infinie car il continue d'essayer de trouver l'image, puis onError est appelé à nouveau, il ne peut pas la trouver et le tout recommence.
borq
30
Pour éviter le risque de boucle infinie, ajoutez simplement un test: <img src = "foo.jpg" onerror = "if (this.src! = 'Error.jog') this.src = 'error.jpg';">
Cela fonctionne très bien. Voici une mise à jour avec une image de secours sur imgur: <img src = "a-missing-image.jpg" alt = "" onerror = "this.src = 'http: ///i.imgur.com/hfM1J8s.png' ">
Utilisez une image d'arrière-plan qui vous permet d'ajouter plusieurs images. Mon cas: image1 est l'image principale, cela proviendra d'un endroit (navigateur faisant une demande) image2 est une image locale par défaut à afficher pendant le chargement de l'image1. Si image1 renvoie n'importe quel type d'erreur, l'utilisateur ne verra aucun changement et ce sera propre pour l'expérience utilisateur
La plupart des navigateurs n'affichent-ils pas une image de «lien rompu» lorsque l'image n'est pas trouvée ... Dans ce cas, la définition de l'arrière-plan ne résoudrait pas le problème.
Justin D.
13
Je ne pense pas que ce soit possible en utilisant uniquement du HTML. Cependant, en utilisant javascript, cela devrait être possible. Bassicly, nous bouclons sur chaque image, testons si elle est complète et si sa largeur naturelle est nulle, cela signifie qu'elle n'a pas été trouvée. Voici le code:
fixBrokenImages =function( url ){var img = document.getElementsByTagName('img');var i=0, l=img.length;for(;i<l;i++){var t = img[i];if(t.naturalWidth ===0){//this image is broken
t.src = url;}}}
En supposant qu'il itempossède une propriété urlqui pourrait être nulle, quand c'est le cas, l'image apparaîtra comme cassée. Cela déclenche l'exécution de l' onerrorexpression d'attribut, comme décrit ci-dessus. Vous devez remplacer l' srcattribut comme décrit ci-dessus, mais vous aurez besoin de jQuery pour accéder à votre altSrc. Impossible de le faire fonctionner avec du JavaScript vanille.
Cela peut sembler un peu hacky mais a sauvé la mise sur mon projet.
un élément img simple n'est pas très flexible, je l'ai donc combiné avec un élément image. de cette façon, aucun CSS n'est nécessaire. lorsqu'une erreur se produit, tous les srcset sont définis sur la version de secours. une image de lien cassé ne s'affiche pas. il ne charge pas les versions d'image inutiles. l'élément d'image prend en charge une conception réactive et plusieurs solutions de rechange pour les types qui ne sont pas pris en charge par le navigateur.
celui-ci est super! soyez conscient du manque de support du navigateur caniuse.com/#feat=picture . pensez à utiliser un polyfill ou une autre solution si vous devez prendre en charge des navigateurs plus anciens comme IE11.
Bien que cela puisse fonctionner, je ne pense pas que cela ajoute de nouvelles informations. La partie onerror est juste du vanilla JavaScript et la liaison src devrait déjà être connue des utilisateurs Angular
Chic
7
Solution simple et soignée impliquant de bonnes réponses et commentaires.
Non, je ne dirais pas non plus que c'est bien. Sans oublier qu'il s'agit probablement d'une refonte d'autres solutions.
Script47
Fonctionne comme un charme! Je vous remercie!
Goehybrid
1
Gareautrain. Je ne voulais pas élégant, je voulais simple et fonctionnel. Merci!
Kit
7
Une solution HTML uniquement, où la seule exigence est que vous connaissiez la taille de l'image que vous insérez. Ne fonctionnera pas pour les images transparentes, car il sert background-imagede remplissage.
Nous pouvons utiliser avec succès background-imagepour lier l'image qui apparaît si l'image donnée est manquante. Ensuite, le seul problème est l'image de l'icône cassée - nous pouvons la supprimer en insérant un très grand caractère vide, poussant ainsi le contenu en dehors de l'affichage de img.
Il n'y a aucun moyen d'être sûr du nombre innombrable de clients (navigateurs) qui tenteront d'afficher votre page. Un aspect à prendre en compte est que les clients de messagerie sont des navigateurs Web de facto et peuvent ne pas gérer de tels trucs et astuces ...
En tant que tel, vous devez également inclure un alt / texte avec une LARGEUR ET UNE HAUTEUR PAR DÉFAUT, comme ceci. Il s'agit d'une solution HTML pure.
alt="NO IMAGE" width="800" height="350"
Donc, l'autre bonne réponse serait légèrement modifiée comme suit:
La solution ci-dessus est incomplète , il a manqué l'attribut src.
this.srcet ne this.attribute('src')sont PAS les mêmes, la première contient la référence complète à l'image, par exemple http://my.host/error.jpg, mais l'attribut conserve simplement la valeur d'origine,error.jpg
Lors de l'utilisation de ce code, je vois Uncaught TypeError: this.attribute is not a functiondans Chrome 43.
John Washam
Utilisez-vous jQuery?
mix3d
onError est déconseillé selon developer.mozilla.org/en-US/docs/Web/HTML/Element/img
comiventor
2
Si vous utilisez Angular 1.x, vous pouvez inclure une directive qui vous permettra de revenir à n'importe quel nombre d'images. L'attribut de secours prend en charge une seule URL, plusieurs URL à l'intérieur d'un tableau ou une expression angulaire utilisant des données de portée:
Ajoutez une nouvelle directive de secours à votre module d'application angulaire:
angular.module('app.services',[]).directive('fallback',['$parse',function($parse){return{restrict:'A',
link:function(scope, element, attrs){var errorCount =0;// Hook the image element error event
angular.element(element).bind('error',function(err){var expressionFunc = $parse(attrs.fallback),
expressionResult,
imageUrl;
expressionResult = expressionFunc(scope);if(typeof expressionResult ==='string'){// The expression result is a string, use it as a url
imageUrl = expressionResult;}elseif(typeof expressionResult ==='object'&& expressionResult instanceofArray){// The expression result is an array, grab an item from the array// and use that as the image url
imageUrl = expressionResult[errorCount];}// Increment the error count so we can keep track// of how many images we have tried
errorCount++;
angular.element(element).attr('src', imageUrl);});}};}])
Idée sympa! Un tableau d'images de secours est une bonne implémentation
Z. Khullah
1
J'ai récemment dû créer un système de secours qui comprenait un nombre illimité d'images de secours. Voici comment je l'ai fait en utilisant une simple fonction JavaScript.
Google a jeté cette page aux mots clés "image fallback html", mais parce que rien de ce qui précède ne m'a aidé, et je cherchais un "support de secours svg pour IE en dessous de 9", j'ai continué à chercher et voici ce que j'ai trouvé:
Si vous avez créé un projet Web dynamique et avez placé l'image requise dans WebContent, vous pouvez accéder à l'image en utilisant le code mentionné ci-dessous dans Spring MVC:
Vous pouvez également créer un dossier nommé img et placer l'image dans le dossier img et placer ce dossier img dans WebContent, puis vous pouvez accéder à l'image en utilisant le code mentionné ci-dessous:
image.setAttribute('src','../icons/<some_image>.png');//check the height attribute.. if image is available then by default it will //be 100 else 0if(image.height ==0){
image.setAttribute('src','../icons/default.png');}
Réponses:
Vous avez demandé une solution HTML uniquement ...
Puisque la première image n'existe pas, le repli (les sprites utilisés sur ce site Web *) s'affichera. Et si vous utilisez un très ancien navigateur qui ne prend pas en charge
object
, il ignorera cette balise et l'utiliseraimg
. Voir le site Web de caniuse pour la compatibilité. Cet élément est largement pris en charge par tous les navigateurs d'IE6 +.* Sauf si l'URL de l'image a changé (à nouveau), auquel cas vous verrez probablement le texte alternatif.
la source
X-Frame-Options
définie surSAMEORIGIN
ou un paramètre plus permissif.Cela fonctionne bien pour moi. Peut-être que vous voulez utiliser JQuery pour accrocher l'événement.
Mis à jour avec le garde d'erreur jacquargs
Mise à jour: solution CSS uniquement J'ai récemment vu Vitaly Friedman démo une excellente solution CSS que je ne connaissais pas. L'idée est d'appliquer la
content
propriété à l'image cassée. Normalement:after
ou:before
ne s'appliquent pas aux images, mais lorsqu'elles sont cassées, elles sont appliquées.Démo: https://jsfiddle.net/uz2gmh2k/2/
Comme le montre le violon, l'image cassée elle-même n'est pas supprimée, mais cela résoudra probablement le problème dans la plupart des cas sans JS ni gouttes de CSS. Si vous devez appliquer différentes images à différents endroits, différenciez-les simplement avec une classe:
.my-special-case img:before { ...
la source
onerror="this.src='error.jpg';this.onerror='';"
J'ai trouvé cette solution dans Spring in Action 3rd Ed.
<img src="../resources/images/Image1.jpg" onerror="this.src='../resources/images/none.jpg'" />
Mise à jour: Ce n'est pas une solution uniquement HTML ...
onerror
est javascriptla source
Utilisez une image d'arrière-plan qui vous permet d'ajouter plusieurs images. Mon cas: image1 est l'image principale, cela proviendra d'un endroit (navigateur faisant une demande) image2 est une image locale par défaut à afficher pendant le chargement de l'image1. Si image1 renvoie n'importe quel type d'erreur, l'utilisateur ne verra aucun changement et ce sera propre pour l'expérience utilisateur
la source
Assurez-vous de saisir les dimensions de l'image et si vous souhaitez que l'image soit tuile ou non.
la source
Je ne pense pas que ce soit possible en utilisant uniquement du HTML. Cependant, en utilisant javascript, cela devrait être possible. Bassicly, nous bouclons sur chaque image, testons si elle est complète et si sa largeur naturelle est nulle, cela signifie qu'elle n'a pas été trouvée. Voici le code:
Utilisez-le comme ceci:
Testé dans Chrome et Firefox
la source
Si vous utilisez Angular / jQuery, cela pourrait vous aider ...
Explication
En supposant qu'il
item
possède une propriétéurl
qui pourrait être nulle, quand c'est le cas, l'image apparaîtra comme cassée. Cela déclenche l'exécution de l'onerror
expression d'attribut, comme décrit ci-dessus. Vous devez remplacer l'src
attribut comme décrit ci-dessus, mais vous aurez besoin de jQuery pour accéder à votre altSrc. Impossible de le faire fonctionner avec du JavaScript vanille.Cela peut sembler un peu hacky mais a sauvé la mise sur mon projet.
la source
un élément img simple n'est pas très flexible, je l'ai donc combiné avec un élément image. de cette façon, aucun CSS n'est nécessaire. lorsqu'une erreur se produit, tous les srcset sont définis sur la version de secours. une image de lien cassé ne s'affiche pas. il ne charge pas les versions d'image inutiles. l'élément d'image prend en charge une conception réactive et plusieurs solutions de rechange pour les types qui ne sont pas pris en charge par le navigateur.
la source
angular2:
la source
Solution simple et soignée impliquant de bonnes réponses et commentaires.
Il résout même le risque de boucle infinie.
A travaillé pour moi.
la source
Une solution HTML uniquement, où la seule exigence est que vous connaissiez la taille de l'image que vous insérez. Ne fonctionnera pas pour les images transparentes, car il sert
background-image
de remplissage.Nous pouvons utiliser avec succès
background-image
pour lier l'image qui apparaît si l'image donnée est manquante. Ensuite, le seul problème est l'image de l'icône cassée - nous pouvons la supprimer en insérant un très grand caractère vide, poussant ainsi le contenu en dehors de l'affichage deimg
.Une solution CSS uniquement (Webkit uniquement)
la source
Il n'y a aucun moyen d'être sûr du nombre innombrable de clients (navigateurs) qui tenteront d'afficher votre page. Un aspect à prendre en compte est que les clients de messagerie sont des navigateurs Web de facto et peuvent ne pas gérer de tels trucs et astuces ...
En tant que tel, vous devez également inclure un alt / texte avec une LARGEUR ET UNE HAUTEUR PAR DÉFAUT, comme ceci. Il s'agit d'une solution HTML pure.
Donc, l'autre bonne réponse serait légèrement modifiée comme suit:
J'ai eu des problèmes avec la balise d'objet dans Chrome, mais j'imagine que cela s'appliquerait également à cela.
Vous pouvez en outre styler l'alt / texte pour être TRÈS GRAND ...
Donc ma réponse est d'utiliser Javascript avec une belle alternative alt / text.
J'ai également trouvé cela intéressant: comment styliser l'attribut alt d'une image
la source
Une version modulable avec JQuery , ajoutez ceci à la fin de votre fichier:
et sur votre
img
tag:la source
La solution ci-dessus est incomplète , il a manqué l'attribut
src
.this.src
et nethis.attribute('src')
sont PAS les mêmes, la première contient la référence complète à l'image, par exemplehttp://my.host/error.jpg
, mais l'attribut conserve simplement la valeur d'origine,error.jpg
Solution correcte
la source
Uncaught TypeError: this.attribute is not a function
dans Chrome 43.Si vous utilisez Angular 1.x, vous pouvez inclure une directive qui vous permettra de revenir à n'importe quel nombre d'images. L'attribut de secours prend en charge une seule URL, plusieurs URL à l'intérieur d'un tableau ou une expression angulaire utilisant des données de portée:
Ajoutez une nouvelle directive de secours à votre module d'application angulaire:
la source
J'ai récemment dû créer un système de secours qui comprenait un nombre illimité d'images de secours. Voici comment je l'ai fait en utilisant une simple fonction JavaScript.
HTML
Javascript
J'ai l'impression que c'est une façon assez légère de gérer de nombreuses images de secours.
la source
En utilisant Jquery, vous pourriez faire quelque chose comme ceci:
la source
Pour n'importe quelle image, utilisez simplement ce code javascript:
où
ptImage
est une<img>
adresse de balise obtenue pardocument.getElementById()
.la source
Google a jeté cette page aux mots clés "image fallback html", mais parce que rien de ce qui précède ne m'a aidé, et je cherchais un "support de secours svg pour IE en dessous de 9", j'ai continué à chercher et voici ce que j'ai trouvé:
Cela peut être hors sujet, mais cela a résolu mon propre problème et cela pourrait aussi aider quelqu'un d'autre.
la source
En plus de la brillante réponse de Patrick , pour ceux d'entre vous qui recherchent une solution js angulaire multiplateforme, c'est parti:
Voici un plunk où je jouais en essayant de trouver la bonne solution: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview
la source
Si vous avez créé un projet Web dynamique et avez placé l'image requise dans WebContent, vous pouvez accéder à l'image en utilisant le code mentionné ci-dessous dans Spring MVC:
Vous pouvez également créer un dossier nommé img et placer l'image dans le dossier img et placer ce dossier img dans WebContent, puis vous pouvez accéder à l'image en utilisant le code mentionné ci-dessous:
la source
Bien!! J'ai trouvé cette méthode pratique, vérifiez que l'attribut height de l'image est égal à 0, puis vous pouvez remplacer l'attribut src par l'image par défaut: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/ Image
la source