Eingabe eines Standardbildes für den Fall, dass das src-Attribut eines HTML <img> ungültig ist?

268

Gibt es eine Möglichkeit, ein Standardbild in einem HTML- <img>Tag zu rendern , falls das srcAttribut ungültig ist (nur HTML verwendet)? Wenn nicht, wie würden Sie es leicht umgehen?

Galilyou
quelle
3
HTML hat keinen Fallback für fehlerhafte Bilder. Sie müssten JavaScript verwenden, um fehlerhafte Bilder zu finden und deren src-Attribut zu ändern.
Blixt
2
@Blixt - Was ist, wenn Ihr Client MS Outlook oder ein anderer EMAIL-Reader ist und Sie kein Javascript haben und die Objektoption nicht funktioniert ... Ich
nehme an

Antworten:

319

Sie haben nach einer reinen HTML- Lösung gefragt ...

 <!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>

Da das erste Bild nicht vorhanden ist, wird der Fallback (die auf dieser Website * verwendeten Sprites) angezeigt. Und wenn Sie einen wirklich alten Browser verwenden, der dies nicht unterstützt object, wird dieses Tag ignoriert und das imgTag verwendet. Siehe caniuse Website für Kompatibilität. Dieses Element wird von allen Browsern ab IE6 + weitgehend unterstützt.

* Sofern sich die URL für das Bild nicht (erneut) geändert hat, wird in diesem Fall wahrscheinlich der Alternativtext angezeigt.

Patrick McElhaney
quelle
3
Es funktionierte für mich in IE8, nachdem ich die DTD für HTML 4.01 eingegeben hatte.
Patrick McElhaney
Dies funktioniert nicht, wenn das nicht vorhandene Bild X-Frame-Optionsauf SAMEORIGINoder eine zulässigere Einstellung eingestellt wurde.
Attila O.
Es funktioniert, aber wenn der Link in object.data nicht vertrauenswürdig ist, kann er alle
möglichen Dinge
1
Das Element 'img' kann nicht im Element 'object' verschachtelt werden.
Matheus Miranda
2
@ Matheus Sicher kann es. In HTML4 kann das Objekt Flow-Inhalte enthalten (fast alles, einschließlich img), und in HTML5 ist es transparent, was bedeutet, dass es jedes gültige HTML5 enthalten kann.
Patrick McElhaney
318

Das funktioniert gut für mich. Vielleicht möchten Sie JQuery verwenden, um das Ereignis zu verknüpfen.

 <img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';">

Aktualisiert mit Jacquargs Error Guard

Aktualisiert: Nur CSS-Lösung Ich habe kürzlich die Vitaly Friedman- Demo als großartige CSS-Lösung gesehen, die mir nicht bekannt war. Die Idee ist, die contentEigenschaft auf das fehlerhafte Bild anzuwenden . Normalerweise :afteroder :beforenicht auf Bilder anwendbar, aber wenn sie kaputt sind, werden sie angewendet.

<img src="nothere.jpg">
<style>
img:before {
    content: ' ';
    display: block;
    position: absolute;
    height: 50px;
    width: 50px;
    background-image: url(ishere.jpg);
</style>

Demo: https://jsfiddle.net/uz2gmh2k/2/

Wie die Geige zeigt, wird das kaputte Bild selbst nicht entfernt, aber dies wird wahrscheinlich das Problem in den meisten Fällen ohne JS oder CSS lösen. Wenn Sie verschiedene Bilder an verschiedenen Orten anwenden müssen, unterscheiden Sie einfach mit einer Klasse:.my-special-case img:before { ...

Svend
quelle
3
Meiner Meinung nach. Dies ist die bessere Antwort. Hier nehmen Mackenmodi einen Fehler an ..... scheint mir ziemlich sicher zu sein. quirksmode.org/dom/events/error.html#t01
n0nag0n
12
Übrigens, wenn error.jpg nicht existiert, verursacht dies eine Endlosschleife, weil es immer wieder versucht, das Bild zu finden, dann wird onError erneut aufgerufen, es kann es nicht finden und das Ganze beginnt von vorne.
Borq
30
Um das Risiko einer Endlosschleife zu vermeiden, fügen Sie einfach einen Test hinzu: <img src = "foo.jpg" onerror = "if (this.src! = 'Error.jog') this.src = 'error.jpg';">
jacquarg
21
Alternativ können Sie schreiben:onerror="this.src='error.jpg';this.onerror='';"
Denilson Sá Maia
6
Wo ist jQuery darin?
Praveen Kumar Purushothaman
64

Fand diese Lösung in Spring in Action 3rd Ed.

<img src="../resources/images/Image1.jpg" onerror="this.src='../resources/images/none.jpg'" />

Update: Dies ist keine reine HTML-Lösung ... onerrorist Javascript

amit bakle
quelle
3
Das funktioniert super. Hier ist ein Update mit einem Fallback-Image auf imgur: <img src = "a-missing-image.jpg" alt = "" onerror = "this.src = 'http: ///i.imgur.com/hfM1J8s.png' ">
Arpo
15

<img style="background-image: url(image1), url(image2);"></img>                                            

Verwenden Sie ein Hintergrundbild, mit dem Sie mehrere Bilder hinzufügen können. Mein Fall: image1 ist das Hauptbild, dies wird von einem Ort (Browser, der eine Anfrage ausführt) abgerufen. Image2 ist ein lokales Standardbild, das angezeigt wird, während image1 geladen wird. Wenn image1 einen Fehler zurückgibt, wird dem Benutzer keine Änderung angezeigt, und dies ist für die Benutzererfahrung sauber

Emiliano Barboza
quelle
Dies funktioniert nur, wenn image1 vollständig undurchsichtig ist. Wenn es wie die meisten Symbolbilder transparent ist, wird image2 durchscheinen.
Jdunning
14
<style type="text/css">
img {
   background-image: url('/images/default.png')
}
</style>

Stellen Sie sicher, dass Sie die Bildabmessungen eingeben und angeben, ob das Bild gekachelt werden soll oder nicht.

Lambacck
quelle
28
Zeigen die meisten Browser kein Bild mit "defektem Link" an, wenn das Bild nicht gefunden wird ... In diesem Fall würde das Problem durch Einstellen des Hintergrunds nicht gelöst.
Justin D.
13

Ich denke nicht, dass es möglich ist, nur HTML zu verwenden. Mit Javascript sollte dies jedoch machbar sein. Bassisch durchlaufen wir jedes Bild, testen, ob es vollständig ist und ob es natürlich ist. Breite ist Null, bedeutet dies, dass es nicht gefunden wurde. Hier ist der 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;
        }
    }
}

Verwenden Sie es so:

 window.onload = function() {
    fixBrokenImages('example.com/image.png');
 }

Getestet in Chrome und Firefox

Pim Jäger
quelle
2
Es funktioniert mit Pim und ist wiederverwendbar, aber ich würde die leichte Option für genau diesen Fall bevorzugen. Vielen Dank :) +1
Galilyou
Sie haben mein ganzes Leben gerettet, Sir.
Beardminator
12

Wenn Sie Angular / jQuery verwenden, kann dies hilfreich sein ...

<img ng-src="{{item.url}}" altSrc="{{item.alt_url}}" onerror="this.src = $(this).attr('altSrc')">

Erläuterung

Angenommen, diese itemhat eine Eigenschaft url, die möglicherweise null ist. Wenn dies der Fall ist, wird das Bild als fehlerhaft angezeigt. Dies löst die Ausführung des onerrorAttributausdrucks aus, wie oben beschrieben. Sie müssen das überschreibensrc Attribut wie oben beschrieben , benötigen jedoch jQuery, um auf Ihr altSrc zuzugreifen. Es konnte nicht mit Vanille-JavaScript funktionieren.

Könnte ein wenig hacky wirken, hat aber den Tag in meinem Projekt gerettet.

Obie
quelle
11

ein einfaches img-element ist nicht sehr flexibel, deshalb habe ich es mit einem bildelement kombiniert. Auf diese Weise wird kein CSS benötigt. Wenn ein Fehler auftritt, werden alle srcset auf die Fallback-Version gesetzt. Ein defektes Linkbild wird nicht angezeigt. Es werden keine nicht benötigten Bildversionen geladen. Das Bildelement unterstützt Responsive Design und mehrere Fallbacks für Typen, die vom Browser nicht unterstützt werden.

<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>
Bapho
quelle
Dieser ist großartig! Beachten Sie die fehlende Browserunterstützung caniuse.com/#feat=picture . Erwägen Sie die Verwendung einer Polyfüllung oder einer anderen Lösung, wenn Sie ältere Browser wie IE11 unterstützen müssen.
Hinrich
7

eckig2:

<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">
user3601578
quelle
1
Obwohl dies funktionieren mag, glaube ich nicht, dass es neue Informationen hinzufügt. Der Fehlerteil ist nur Vanille-JavaScript und die src-Bindung sollte Angular-Benutzern bereits bekannt sein
Chic
7

Einfache und übersichtliche Lösung mit einigen guten Antworten und Kommentaren.

<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">

Es löst sogar das Endlosschleifenrisiko.

Hat für mich gearbeitet.

manish kumar
quelle
IMO, das sieht definitiv nicht elegant aus.
Script47
1
@ Script47 Es ist ordentlich, ich wiederhole ordentlich
manish kumar
1
Nein, ich würde auch nicht sagen, dass es ordentlich ist. Ganz zu schweigen davon, dass dies wahrscheinlich eine Wiederholung anderer Lösungen ist.
Script47
Klappt wunderbar! Danke dir!
Goehybrid
1
Lebensretter. Ich wollte nicht elegant, ich wollte einfach und arbeitend. Vielen Dank!
Kit
7

Ein HTML einzige Lösung, wo die einzige Voraussetzung ist , dass Sie wissen , die Größe des Bildes , das Sie Einfügen. Funktioniert nicht für transparente Bilder, da es background-imageals Füllmaterial verwendet wird.

Wir können background-imagedas Bild, das angezeigt wird, wenn das angegebene Bild fehlt, erfolgreich verknüpfen. Dann ist das einzige Problem das kaputte Symbolbild - wir können es entfernen, indem wir ein sehr großes leeres Zeichen einfügen und so den Inhalt außerhalb der Anzeige von verschieben 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


Eine reine CSS-Lösung (nur Webkit)

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

eithed
quelle
4

Es gibt keine Möglichkeit, sicher zu sein, wie viele Clients (Browser) versuchen, Ihre Seite anzuzeigen. Ein zu berücksichtigender Aspekt ist, dass E-Mail-Clients defakte Webbrowser sind und möglicherweise nicht mit solchen Tricks umgehen ...

Als solches sollten Sie AUCH einen Alt / Text mit einer STANDARDBREITE und -HÖHE wie diesen einfügen. Dies ist eine reine HTML-Lösung.

alt="NO IMAGE" width="800" height="350"

Die andere gute Antwort würde also wie folgt leicht modifiziert:

<img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="NO IMAGE" width="800" height="350">

Ich hatte Probleme mit dem Objekt-Tag in Chrome, aber ich würde mir vorstellen, dass dies auch dafür gilt.

Sie können den Alt / Text so gestalten, dass er SEHR GROSS ist ...

Meine Antwort ist also, Javascript mit einem schönen Alt / Text-Fallback zu verwenden.

Ich fand das auch interessant: Wie man das Alt-Attribut eines Bildes stylt

Xofo
quelle
3

Fügen Sie eine modulierbare Version mit JQuery am Ende Ihrer Datei hinzu:

<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>

und auf deinem imgTag:

<img src="..." data-src-error="..." />
Kevin Robatel
quelle
3

Die obige Lösung ist unvollständig , sie hat das Attribut verfehlt src.

this.srcund this.attribute('src')sind NICHT gleich, der erste enthält zum Beispiel den vollständigen Verweis auf das Bild http://my.host/error.jpg, aber das Attribut behält nur den ursprünglichen Wert bei.error.jpg

Richtige Lösung

<img src="foo.jpg" onerror="if (this.src != 'error.jpg' && this.attribute('src') != 'error.jpg') this.src = 'error.jpg';" />
Seb
quelle
3
Wenn ich diesen Code verwende, sehe ich Uncaught TypeError: this.attribute is not a functionin Chrome 43.
John Washam
Verwenden Sie jQuery?
mix3d
onError ist gemäß developer.mozilla.org/en-US/docs/Web/HTML/Element/img
comiventor
2

Wenn Sie Angular 1.x verwenden, können Sie eine Direktive einfügen, mit der Sie auf eine beliebige Anzahl von Bildern zurückgreifen können. Das Fallback-Attribut unterstützt eine einzelne URL, mehrere URLs innerhalb eines Arrays oder einen Winkelausdruck unter Verwendung von Bereichsdaten:

<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" />

Fügen Sie Ihrem Winkel-App-Modul eine neue Fallback-Direktive hinzu:

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);
                });
            }
        };
    }])
Rob Evans
quelle
Tolle Idee! Ein Array aus Fallback-Bildern ist eine gute Implementierung
Z. Khullah
1

Ich musste kürzlich ein Fallback-System bauen, das eine beliebige Anzahl von Fallback-Bildern enthielt. So habe ich es mit einer einfachen JavaScript-Funktion gemacht.

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;
}

Ich denke, es ist eine ziemlich leichte Art, mit vielen Fallback-Bildern umzugehen.

Wütend
quelle
0

Mit Jquery können Sie Folgendes tun:

$(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");
    }
});
Jon
quelle
0

Verwenden Sie für jedes Bild einfach diesen Javascript-Code:

if (ptImage.naturalWidth == 0)
    ptImage.src = '../../../../icons/blank.png';

Wo ptImageist eine <img>Tag-Adresse erhalten von document.getElementById().

José Esteves Pereira
quelle
0

Google hat diese Seite mit den Schlüsselwörtern "image fallback html" verworfen. Da mir jedoch keines der oben genannten Elemente geholfen hat und ich nach einer "SVG-Fallback-Unterstützung für IE unter 9" gesucht habe, habe ich weiter gesucht und Folgendes gefunden:

<img src="base-image.svg" alt="picture" />
<!--[if (lte IE 8)|(!IE)]><image src="fallback-image.png" alt="picture" /><![endif]-->

Es mag nicht zum Thema gehören, aber es hat mein eigenes Problem gelöst und es könnte auch jemand anderem helfen.

Sándor Zuboly
quelle
0

Zusätzlich zu Patricks brillanter Antwort für diejenigen unter Ihnen, die nach einer plattformübergreifenden eckigen js-Lösung suchen, können Sie Folgendes tun:

<object type="image/png" data-ng-attr-data="{{ url || 'data:' }}">
    <!-- any html as a fallback -->
</object>

Hier ist ein Plunk, in dem ich versucht habe, die richtige Lösung zu finden: http://plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview

Sunsay
quelle
0

Wenn Sie ein dynamisches Webprojekt erstellt und das erforderliche Bild in WebContent platziert haben, können Sie mit dem folgenden Code in Spring MVC auf das Bild zugreifen:

<img src="Refresh.png" alt="Refresh" height="50" width="50">

Sie können auch einen Ordner mit dem Namen img erstellen und das Bild im Ordner img ablegen und diesen img-Ordner in WebContent ablegen. Anschließend können Sie mit dem folgenden Code auf das Bild zugreifen:

<img src="img/Refresh.png" alt="Refresh" height="50" width="50">
Yoshita Mahajan
quelle
-2

Gut!! Ich fand diesen Weg praktisch. Überprüfen Sie, ob das Höhenattribut des Bildes 0 ist. Dann können Sie das src-Attribut mit dem Standardbild überschreiben: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/ Bild

 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');
  }
suhail
quelle