属性が無効な<img>
場合src
(HTMLのみを使用)、HTML タグでデフォルト画像をレンダリングする方法はありますか?そうでない場合、それを回避するための軽量な方法は何ですか?
属性が無効な<img>
場合src
(HTMLのみを使用)、HTML タグでデフォルト画像をレンダリングする方法はありますか?そうでない場合、それを回避するための軽量な方法は何ですか?
回答:
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が(再度)変更されない限り、その場合はおそらく代替テキストが表示されます。
X-Frame-Options
設定されている場合は機能しませんSAMEORIGIN
。
これは私にとってはうまくいきます。おそらく、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 { ...
onerror="this.src='error.jpg';this.onerror='';"
このソリューションはSpring in Action 3rd Edで見つかりました。
<img src="../resources/images/Image1.jpg" onerror="this.src='../resources/images/none.jpg'" />
更新:
これはHTMLのみのソリューションではありません... onerror
JavaScriptです
<img style="background-image: url(image1), url(image2);"></img>
複数の画像を追加できる背景画像を使用します。私の場合:image1はメインイメージです。これはどこかから取得されます(ブラウザがリクエストを実行します)image2は、image1のロード中に表示されるデフォルトのローカルイメージです。image1がなんらかのエラーを返す場合、ユーザーには変更が表示されず、これはユーザーエクスペリエンスにとってクリーンです。
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でテスト済み
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では動作しませんでした。
少しハックに思えるかもしれませんが、私のプロジェクトの日を節約しました。
単純な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>
angular2:
<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">
いくつかの良い答えとコメントを含むシンプルで端正なソリューション。
<img src="foo.jpg" onerror="this.src='error.jpg';this.onerror='';">
無限ループのリスクも解決します。
私のために働いた。
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
無数のクライアント(ブラウザ)がページを表示しようとすることを確認する方法はありません。考慮すべき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属性をスタイルする方法
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="..." />
上記のソリューションは不完全であり、属性がありませんsrc
でした。
this.src
とthis.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';" />
Uncaught TypeError: this.attribute is not a function
クローム43に
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);
});
}
};
}])
私は最近、任意の数のフォールバックイメージを含むフォールバックシステムを構築する必要がありました。これが、単純な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;
}
多くのフォールバック画像を処理するためのかなり軽量な方法だと思います。
任意の画像については、次のJavaScriptコードを使用してください。
if (ptImage.naturalWidth == 0)
ptImage.src = '../../../../icons/blank.png';
どこptImage
で<img>
で得られたタグアドレスdocument.getElementById()
。
グーグルはこのページを「画像フォールバックhtml」キーワードに放り出したが、上記のどれも役に立たず、「IEの9以下のsvgフォールバックサポート」を探していたので、検索を続けたところ、これが見つかった。
<img src="base-image.svg" alt="picture" />
<!--[if (lte IE 8)|(!IE)]><image src="fallback-image.png" alt="picture" /><![endif]-->
それは話題外かもしれませんが、それは私の自身の問題を解決し、それは他の誰かを助けるかもしれません。
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
動的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">
上手!!私はこの方法が便利だと思ったので、画像の高さ属性が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');
}