Existe-t-il un moyen de rendre une image par défaut dans une <img>
balise HTML , au cas où l' src
attribut n'est pas valide (en utilisant uniquement du HTML)? Sinon, quelle serait votre façon légère de contourner ce problème?
Existe-t-il un moyen de rendre une image par défaut dans une <img>
balise HTML , au cas où l' src
attribut n'est pas valide (en utilisant uniquement du HTML)? Sinon, quelle serait votre façon légère de contourner ce problème?
Réponses:
Vous avez demandé une solution HTML uniquement ...
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>Object Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<p>
<object data="http://stackoverflow.com/does-not-exist.png" type="image/png">
<img src="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.
X-Frame-Options
définie sur SAMEORIGIN
ou un paramètre plus permissif.
Cela fonctionne bien pour moi. Peut-être que vous voulez utiliser JQuery pour accrocher l'événement.
<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';">
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.
<img src="nothere.jpg">
<style>
img:before {
content: ' ';
display: block;
position: absolute;
height: 50px;
width: 50px;
background-image: url(ishere.jpg);
</style>
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 { ...
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 javascript
<img style="background-image: url(image1), url(image2);"></img>
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
<style type="text/css">
img {
background-image: url('/images/default.png')
}
</style>
Assurez-vous de saisir les dimensions de l'image et si vous souhaitez que l'image soit tuile ou non.
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;
}
}
}
Utilisez-le comme ceci:
window.onload = function() {
fixBrokenImages('example.com/image.png');
}
Testé dans Chrome et Firefox
Si vous utilisez Angular / jQuery, cela pourrait vous aider ...
<img ng-src="{{item.url}}" altSrc="{{item.alt_url}}" onerror="this.src = $(this).attr('altSrc')">
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.
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.
<picture>
<source id="s1" srcset="image1_not_supported_by_browser.webp" type="image/webp">
<source id="s2" srcset="image2_broken_link.png" type="image/png">
<img src="image3_fallback.jpg" alt="" onerror="this.onerror=null;document.getElementById('s1').srcset=document.getElementById('s2').srcset=this.src;">
</picture>
angular2:
<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">
Solution simple et soignée impliquant de bonnes réponses et commentaires.
<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">
Il résout même le risque de boucle infinie.
A travaillé pour moi.
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 de img
.
img {
background-image: url("http://placehold.it/200x200");
overflow: hidden;
}
img:before {
content: " ";
font-size: 1000px;
}
This image is missing:
<img src="a.jpg" style="width: 200px; height: 200px"/><br/>
And is displaying the placeholder
Une solution CSS uniquement (Webkit uniquement)
img:before {
content: " ";
font-size: 1000px;
background-image: url("http://placehold.it/200x200");
display: block;
width: 200px;
height: 200px;
position: relative;
z-index: 0;
margin-bottom: -16px;
}
This image is there:
<img src="http://placehold.it/100x100"/><br/>
This image is missing:
<img src="a.jpg"/><br/>
And is displaying the placeholder
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:
<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="NO IMAGE" width="800" height="350">
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
Une version modulable avec JQuery , ajoutez ceci à la fin de votre fichier:
<script>
$(function() {
$('img[data-src-error]').error(function() {
var o = $(this);
var errorSrc = o.attr('data-src-error');
if (o.attr('src') != errorSrc) {
o.attr('src', errorSrc);
}
});
});
</script>
et sur votre img
tag:
<img src="..." data-src-error="..." />
La solution ci-dessus est incomplète , il a manqué l'attribut src
.
this.src
et 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
Solution correcte
<img src="foo.jpg" onerror="if (this.src != 'error.jpg' && this.attribute('src') != 'error.jpg') this.src = 'error.jpg';" />
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:
<img ng-src="myFirstImage.png" fallback="'fallback1.png'" />
<img ng-src="myFirstImage.png" fallback="['fallback1.png', 'fallback2.png']" />
<img ng-src="myFirstImage.png" fallback="myData.arrayOfImagesToFallbackTo" />
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;
} else if (typeof expressionResult === 'object' && expressionResult instanceof Array) {
// 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);
});
}
};
}])
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
<img src="some_image.tiff"
onerror="fallBackImg(this);"
data-fallIndex="1"
data-fallback1="some_image.png"
data-fallback2="some_image.jpg">
Javascript
function fallBackImg(elem){
elem.onerror = null;
let index = +elem.dataset.fallIndex;
elem.src = elem.dataset[`fallback${index}`];
index++;
elem.dataset.fallbackindex = index;
}
J'ai l'impression que c'est une façon assez légère de gérer de nombreuses images de secours.
Pour n'importe quelle image, utilisez simplement ce code javascript:
if (ptImage.naturalWidth == 0)
ptImage.src = '../../../../icons/blank.png';
où ptImage
est une <img>
adresse de balise obtenue par document.getElementById()
.
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é:
<img src="base-image.svg" alt="picture" />
<!--[if (lte IE 8)|(!IE)]><image src="fallback-image.png" alt="picture" /><![endif]-->
Cela peut être hors sujet, mais cela a résolu mon propre problème et cela pourrait aussi aider quelqu'un d'autre.
En plus de la brillante réponse de Patrick , pour ceux d'entre vous qui recherchent une solution js angulaire multiplateforme, c'est parti:
<object type="image/png" data-ng-attr-data="{{ url || 'data:' }}">
<!-- any html as a fallback -->
</object>
Voici un plunk où je jouais en essayant de trouver la bonne solution: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview
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:
<img src="Refresh.png" alt="Refresh" height="50" width="50">
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:
<img src="img/Refresh.png" alt="Refresh" height="50" width="50">
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
image.setAttribute('src','../icons/<some_image>.png');
//check the height attribute.. if image is available then by default it will
//be 100 else 0
if(image.height == 0){
image.setAttribute('src','../icons/default.png');
}