HTML <img>のsrc属性が無効な場合のデフォルト画像の入力?


268

属性が無効な<img>場合src(HTMLのみを使用)、HTML タグでデフォルト画像をレンダリングする方法はありますか?そうでない場合、それを回避するための軽量な方法は何ですか?


3
HTMLには、壊れた画像のフォールバックはありません。JavaScriptを使用して壊れた画像を見つけ、そのsrc属性を変更する必要があります。
Blixt 2009年

2
@Blixt -どのようなあなたのクライアントはMS Outlookまたは他の何らかのEMAILリーダーであり、あなたはJavascriptを持っていない、とオブジェクトのオプションが仕事をしません...私は唯一のソリューションを想定した場合には、ALT /テキストです
Xofo

回答:


319

HTMLのみのソリューションを要求しました...

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

最初の画像が存在しないため、フォールバック(このWebサイトで使用されているスプライト*)が表示されます。また、をサポートしていない非常に古いブラウザをobject使用している場合、そのタグは無視され、タグが使用されますimg。互換性については、caniuseの Webサイトを参照してください。この要素は、IE6以降のすべてのブラウザで広くサポートされています。

*画像のURLが(再度)変更されない限り、その場合はおそらく代替テキストが表示されます。


3
それは私がHTML 4.01のDTDを入れた後IE8で私のために働いた。
Patrick McElhaney、2009年

これは、存在しないイメージが許容値以上にX-Frame-Options設定されている場合は機能しませんSAMEORIGIN
Attila O. 2013年

動作しますが、object.dataのリンクが信頼されていない場合は、あらゆる種類のものをロードできます...
Michael_Scharf

1
要素「img」は要素「object」内にネストできません。
Matheus Miranda

2
@マテウス確かにできます。HTML4では、オブジェクトにフローコンテンツ(imgを含むほとんどすべて)を含めることができ、HTML5では透過的です。つまり、有効なHTML5を含めることができます。
Patrick McElhaney 2017年

318

これは私にとってはうまくいきます。おそらく、JQueryを使用してイベントをフックしたいでしょう。

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

jacquargsエラーガードで更新

更新:CSSのみのソリューション 最近Vitaly Friedmanのデモを見て、私が知らなかった優れたCSSソリューションを見つけました。contentプロパティは、壊れた画像にプロパティを適用することです。通常:afterまたは:before画像には適用されませんが、壊れた場合は適用されます。

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

デモ:https : //jsfiddle.net/uz2gmh2k/2/

フィドルが示すように、壊れた画像自体は削除されませんが、これはおそらく、JSやCSSのゴブがないほとんどの場合の問題を解決するでしょう。異なる場所に異なる画像を適用する必要がある場合は、クラスで区別するだけです。.my-special-case img:before { ...


3
私の考えでは。これがより良い答えです。ここでは、quirksmodesがonerrorに対応します。quirksmode.org/dom/events/error.html#t01
n0nag0n

12
ところで、error.jpgが存在しない場合は、画像の検索を繰り返し続けるため無限ループが発生し、onErrorが再度呼び出されて、画像が見つかりませんでした。
borq 2013年

30
無限ループのリスクを回避するには、テストを追加します。<img src = "foo.jpg" onerror = "if(this.src!= 'error.jog')this.src = 'error.jpg';">
jacquarg

21
別の方法として、次のように記述することができます:onerror="this.src='error.jpg';this.onerror='';"
デニウソンSáマイア

6
これのjQueryはどこですか?
Praveen Kumar Purushothaman、2015年

64

このソリューションはSpring in Action 3rd Edで見つかりました。

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

更新: これはHTMLのみのソリューションではありません... onerrorJavaScriptです


3
これはうまくいきます。次に、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>                                            

複数の画像を追加できる背景画像を使用します。私の場合:image1はメインイメージです。これはどこかから取得されます(ブラウザがリクエストを実行します)image2は、image1のロード中に表示されるデフォルトのローカルイメージです。image1がなんらかのエラーを返す場合、ユーザーには変更が表示されず、これはユーザーエクスペリエンスにとってクリーンです。



これは、image1が完全に不透明な場合にのみ機能します。ほとんどのアイコン画像のように透明性がある場合、image2は透けて見えます。
2017

14
<style type="text/css">
img {
   background-image: url('/images/default.png')
}
</style>

画像のサイズと、画像を並べて表示するかどうかを必ず入力してください。


28
ほとんどのブラウザは、画像が見つからないときに「リンク切れ」画像を表示しません...その場合、背景を設定しても問題は解決しません。
ジャスティンD.

13

HTMLだけでは実現できないと思います。ただし、JavaScriptを使用すれば、これは可能です。基本的に、各画像をループし、それが完全であるかどうかをテストし、それがnaturalWidthがゼロである場合、それはそれが見つからないことを意味します。これがコードです:

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

次のように使用します。

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

ChromeおよびFirefoxでテスト済み


2
これはPimで動作し、完全に再利用できますが、この場合は軽量オプションを使用します。
どうも

あなたは私の命をすべて救ってくれました。
Beardminator 2014年

12

Angular / jQueryを使用している場合、これが役立つかもしれません...

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

説明

nullの可能性itemがあるプロパティがあると仮定すると、そのurl場合、画像は壊れているように見えます。onerror上記のように、属性式の実行がトリガーされます。src上記のように属性をオーバーライドする必要がありますが、altSrcにアクセスするにはjQueryが必要です。バニラJavaScriptでは動作しませんでした。

少しハックに思えるかもしれませんが、私のプロジェクトの日を節約しました。


11

単純なimg-elementはあまり柔軟ではないため、picture-elementと組み合わせました。この方法では、CSSは必要ありません。エラーが発生すると、すべてのsrcsetがフォールバックバージョンに設定されます。リンク切れの画像が表示されません。不要なイメージバージョンはロードしません。picture-elementは、ブラウザーでサポートされていないタイプのレスポンシブデザインと複数のフォールバックをサポートします。

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

これは素晴らしい!欠落しているブラウザーサポートcaniuse.com/#feat=pictureに注意してください。IE11などの古いブラウザをサポートする必要がある場合は、ポリフィルまたは別のソリューションの使用を検討してください。
Hinrich

7

angular2:

<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">

1
これでうまくいくかもしれませんが、新しい情報が追加されるとは思いません。onerror部分は単なるJavaScriptであり、srcバインディングはAngularユーザーにすでに知られているはずです
シックな

7

いくつかの良い答えとコメントを含むシンプルで端正なソリューション。

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

無限ループのリスクも解決します。

私のために働いた。


IMO、これは間違いなくエレガントに見えません。
Script47

1
@ Script47そのきちんとした、私はきちんと繰り返す
マニッシュクマー

1
いいえ、それもきちんとしているとは言えません。言うまでもなく、これはおそらく他のソリューションのリハッシュです。
Script47

魅力的な作品!ありがとうございました!
Goehybrid

1
命の恩人。私はエレガントではなく、シンプルで働きたいと思っていました。ありがとう!
キット

7

HTMLのみのソリューション。唯一の要件は、挿入する画像のサイズを知っていることです。background-imageフィラーとして使用するため、透明な画像には機能しません。

background-image指定された画像がない場合に表示される画像を正常にリンクするために使用できます。次に、唯一の問題は、壊れたアイコン画像です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


CSSのみのソリューション(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


4

無数のクライアント(ブラウザ)がページを表示しようとすることを確認する方法はありません。考慮すべき1つの側面は、電子メールクライアントが事実上のWebブラウザーであり、そのようなだまし絵を処理できない可能性があることです...

このように、DEFAULT WIDTHとHEIGHTを含むalt / textもこのように含める必要があります。これは純粋なHTMLソリューションです。

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

したがって、他の良い答えは次のように少し変更されます:

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

Chromeのオブジェクトタグに問題がありましたが、これも当てはまると思います。

さらに、alt / textのスタイルを非常に大きくすることができます...

だから私の答えは、素晴らしいalt / textフォールバックを持つJavaScriptを使用することです。

私はこれも面白いと思いました:画像のalt属性をスタイルする方法


3

JQueryを使用したモジュール化可能なバージョン。これをファイルの最後に追加します。

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

そしてあなたのimgタグで:

<img src="..." data-src-error="..." />

3

上記のソリューションは不完全であり、属性がありませんsrcでした。

this.srcthis.attribute('src')同じではありません。最初の画像には画像への完全な参照が含まれてhttp://my.host/error.jpgいますが、属性は元の値を保持しているだけです。error.jpg

正しい解決策

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

3
このコードを使用する場合は、私が見Uncaught TypeError: this.attribute is not a functionクローム43に
ジョンWasham

jQueryを使用していますか?
mix3d、2015

onErrorは、developer.mozilla.org
en

2

Angular 1.xを使用している場合は、任意の数の画像にフォールバックできるディレクティブを含めることができます。フォールバック属性は、単一のURL、配列内の複数のURL、またはスコープデータを使用した角度式をサポートします。

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

Angular Appモジュールに新しいフォールバックディレクティブを追加します。

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

クールなアイデア!フォールバック画像からの配列は良い実装です
Z. Khullah 2017

1

私は最近、任意の数のフォールバックイメージを含むフォールバックシステムを構築する必要がありました。これが、単純な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;
}

多くのフォールバック画像を処理するためのかなり軽量な方法だと思います。


onErrorは、developer.mozilla.org
en

0

Jqueryを使用すると、次のようなことができます:

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

0

任意の画像については、次のJavaScriptコードを使用してください。

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

どこptImage<img>で得られたタグアドレスdocument.getElementById()


0

グーグルはこのページを「画像フォールバックhtml」キーワードに放り出したが、上記のどれも役に立たず、「IEの9以下のsvgフォールバックサポート」を探していたので、検索を続けたところ、これが見つかった。

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

それは話題外かもしれませんが、それは私の自身の問題を解決し、それは他の誰かを助けるかもしれません。


0

Patrickの素晴らしい答えに加えて、クロスプラットフォームのアンギュラーjsソリューションを探している人のために、ここに行きます:

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

これが私が正しい解決策を見つけようとして遊んでいた秘訣です:http : //plnkr.co/edit/nL6FQ6kMK33NJeW8DVDY?p=preview


0

動的Webプロジェクトを作成し、必要な画像をWebContentに配置した場合、Spring MVCで以下のコードを使用して画像にアクセスできます。

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

imgという名前のフォルダーを作成し、imgフォルダー内に画像を配置し、そのimgフォルダーをWebContent内に配置すると、以下のコードを使用して画像にアクセスできます。

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

-2

上手!!私はこの方法が便利だと思ったので、画像の高さ属性が0であることを確認してから、src属性をデフォルトの画像で上書きできます:https : //developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/画像

 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');
  }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.