Existe-t-il un moyen de restituer une image par défaut dans une balise HTML <img>
, au cas où l'attribut src
serait invalide (avec uniquement du code HTML)? Si non, quelle serait votre façon légère de contourner le problème?
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>
Étant donné que la première image n'existe pas, le repli (les sprites utilisés sur ce site Web *) s'affichera. Et si vous utilisez un ancien navigateur vraiment qui ne prend pas en charge object
, il ignorera simplement cette balise et utilisera la balise img
. Voir caniuse site web pour la compatibilité. Depuis 2018, cet élément est largement pris en charge par tous les navigateurs à partir de IE6 +.
* À moins que l'URL de l'image ne soit modifiée (à nouveau), auquel cas vous verrez probablement le texte de remplacement.
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';">
Mise à 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 propriété content
à l'image endommagée. Normalement, :after
ou :before
ne s'appliquent pas aux images, mais lorsqu'elles sont brisé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 brisé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 gobs de CSS. Si vous devez appliquer différentes images à différents endroits, différenciez-vous simplement avec une classe: .my-special-case img:before { ...
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
<style type="text/css">
img {
background-image: url('/images/default.png')
}
</style>
Assurez-vous de saisir les dimensions de l’image et indiquez si vous souhaitez que l’image soit mise en mosaïque ou non.
Si vous utilisez Angular/jQuery, cela pourrait aider ...
<img ng-src="{{item.url}}" altSrc="{{item.alt_url}}" onerror="this.src = $(this).attr('altSrc')">
Explication
En supposant que item
ait une propriété url
qui pourrait être nulle, l'image apparaîtra alors comme étant cassée. Cela déclenche l'exécution de l'expression de l'attribut onerror
, comme décrit ci-dessus. Vous devez remplacer l'attribut src
comme décrit ci-dessus, mais vous aurez besoin de jQuery pour accéder à votre altSrc. Impossible de le faire fonctionner avec JavaScript JavaScript.
Cela peut sembler un peu hacky mais a sauvé la journée de mon projet.
Je ne pense pas qu'il soit possible d'utiliser uniquement du code HTML. Cependant, l'utilisation de javascript devrait être faisable. Bassicly on boucle sur chaque image, teste si elle est complète et si c'est naturelWidth est zéro alors cela signifie qu'il n'est pas trouvé. 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
<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, elle proviendra d'un endroit (navigateur effectuant une demande) image2 est une image locale par défaut à afficher pendant le chargement de l'image1. Si image1 renvoie tout type d'erreur, l'utilisateur ne verra aucun changement et ce sera propre pour l'expérience utilisateur.
un simple img-element n'est pas très flexible, je l'ai donc combiné avec un élément d'image. De cette façon, aucun CSS n'est nécessaire. en cas d'erreur, tous les srcset sont définis sur la version de secours. une image de lien brisé ne s'affiche pas. il ne charge pas les versions d'image inutiles. l'élément picture prend en charge la conception adaptative et plusieurs solutions de repli pour les types non 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>
Une solution uniquement HTML, 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 utilise background-image
en tant que 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 d’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 uniquement CSS (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; }
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
Ou, sur jsfiddle: https://jsfiddle.net/xehndm3u/9/
angular2:
<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">
Il n’ya aucun moyen d’être certain du nombre incroyable de clients (navigateurs) qui tenteront d’afficher votre page. Un aspect à considérer est que les clients de messagerie sont des navigateurs web de facto et ne peuvent pas gérer de tels trucs ...
En tant que tel, vous devriez également inclure un alt/text avec une largeur par défaut et une hauteur, comme ceci. Ceci est 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'avais des problèmes avec la balise d'objet dans Chrome, mais j'imagine que cela s'appliquerait également à cela.
Vous pouvez en outre attribuer un style TRÈS GRAND à l'alt/texte ...
Donc, ma réponse est d'utiliser Javascript avec un repli Nice alt/text.
J'ai aussi trouvé cela intéressant: comment attribuer un style à 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 tag img
:
<img src="..." data-src-error="..." />
La solution ci-dessus est incomplète, l'attribut src
n'a pas été trouvé.
this.src
et this.attribute('src')
NE SONT PAS identiques, le premier 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';" />
Si vous utilisez Angular 1.x, vous pouvez inclure une directive qui vous permettra de vous replier sur un nombre illimité d’images. L'attribut fallback prend en charge une seule URL, plusieurs URL à l'intérieur d'un tableau ou une expression angular à l'aide 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 angular:
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);
});
}
};
}])
Solution simple et soignée impliquant de bonnes réponses et commentaires.
<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">
Cela résout même le risque de boucle infinie.
Travaillé pour moi.
Si vous avez créé un projet Web dynamique et avez placé l'image requise dans WebContent, vous pouvez y accéder 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 dans WebContent. Vous pourrez alors accéder à l'image à l'aide du code mentionné ci-dessous:
<img src="img/Refresh.png" alt="Refresh" height="50" width="50">
En plus de Patrick réponse géniale, pour ceux d'entre vous qui recherchent une solution multiplate-forme angular js, voici ce que vous effectuez:
<object type="image/png" data-ng-attr-data="{{ url || 'data:' }}">
<!-- any html as a fallback -->
</object>
Voici une partie où je jouais en essayant de trouver la bonne solution: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview
En utilisant Jquery, vous pouvez faire quelque chose comme ceci:
$(document).ready(function() {
if ($("img").attr("src") != null)
{
if ($("img").attr("src").toString() == "")
{
$("img").attr("src", "images/default.jpg");
}
}
else
{
$("img").attr("src", "images/default.jpg");
}
});
Pour n'importe quelle image, utilisez simplement ce code javascript:
if (ptImage.naturalWidth == 0)
ptImage.src = '../../../../icons/blank.png';
où ptImage
est une adresse de balise <img>
obtenue par document.getElementById()
.
Google a jeté cette page sur les mots-clés "image de repli html", mais comme aucune de ces réponses ne m'a aidé, et que je recherchais un "support de repli de svg pour IE inférieur à 9", j'ai poursuivi la recherche 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 pourrait également aider quelqu'un d'autre.