输入一个默认图像的情况下src属性的html <是无效的?

是否有任何方法在HTML <img>标记中呈现默认图像,以防src属性无效(仅使用HTML)?如果不是,你会用什么轻量级的方式来解决这个问题?

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

请务必输入图像的尺寸,以及是否希望图像平铺。

你要求一个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="https://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>

由于第一个图像不存在,将显示回退(在这个网站上使用的精灵*)。如果你使用的是不支持object真的旧浏览器,它将忽略该标记并使用img标记。参见caniuse网站了解兼容性。从IE6+开始的所有浏览器都广泛支持该元素。

*除非图片的URL改变了(再次),在这种情况下,你可能会看到alt文本。

使用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");
}
});

这对我来说很有效。也许你想用JQuery来挂钩事件。

 <img src="foo.jpg" onerror="if (this.src != 'error.jpg') this.src = 'error.jpg';" alt="add alternative text here">

更新了jacquargs错误保护

更新:CSS唯一的解决方案 我最近看到维塔利·弗里德曼演示了一个我不知道的很棒的CSS解决方案。其思想是将content属性应用于破碎的图像。通常:after:before不应用于图像,但当它们被破坏时,它们会被应用

<img src="nothere.jpg" alt="add alternative text here">
<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 { ... 进行区分

我认为仅仅使用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中测试

对于任何图像,只需使用以下javascript代码:

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

其中ptImage是由document.getElementById()获得的<img>标记地址。

在Spring in Action第三版中找到了这个解决方案。

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

< >强更新: 这不是一个只有HTML的解决方案…onerror是javascript

如果你正在使用Angular/jQuery,那么这可能会有帮助……

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

解释

假设item有一个可能为空的属性url,当它为空时,图像将显示为破碎。这触发onerror属性表达式的执行,如上所述。你需要如上所述重写src属性,但你需要jQuery来访问你的altSrc。无法让它与普通JavaScript一起工作。

可能看起来有点俗气,但挽救了我的项目。

上述解决方案是不完整的,它错过了属性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';" />

没有办法确定无数的客户端(浏览器)将试图查看您的页面。需要考虑的一个方面是,电子邮件客户端实际上是web浏览器,可能无法处理这种诡计……

因此,你也应该包括一个alt/文本的默认宽度和高度,就像这样。这是一个纯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/文本非常大…

所以我的答案是使用Javascript和一个不错的alt/text回退。

我还发现这个很有趣:如何样式一个图像's 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="..." />

angular2:

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

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

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

Use background image that let you add multiple images. My case: image1 is the main image, this will get from some place (browser doing a request) image2 is a default local image to show while image1 is being loaded. If image1 returns any kind of error, the user won't see any change and this will be clean for user experience

简单的img-element不是很灵活,所以我将它与picture-element结合在一起。这样就不需要CSS了。当发生错误时,所有srcset都被设置为回退版本。断开的链接图像不显示。它不会加载不需要的图像版本。图片元素支持响应式设计,并为浏览器不支持的类型提供多种回退。

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

如果你使用的是Angular 1。X你可以包含一个指令,允许你回退到任意数量的图像。fallback属性支持单个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模块中添加一个新的fallback指令:

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

谷歌抛出了这个页面的“图像回退html”关键字,但因为上面没有帮助我,我正在寻找一个“svg回退支持IE低于9”,我继续搜索,这是我发现的:

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

这可能离题了,但它解决了我自己的问题,也可能帮助到其他人。

< p > ! ! 我发现这种方法很方便,检查图像的高度属性为0,然后你可以用默认的图像覆盖src属性: https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image < / p >
 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');
}

除了帕特里克的的精彩答案,对于那些正在寻找跨平台angular 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">

简单利落的解决方案,包括一些好的答案和评论。

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

它甚至解决了无限循环风险。

为我工作。

更新:2022年(仍然适用于chrome)

我最近不得不构建一个包括任意数量的备份映像的备份系统。下面是我如何使用一个简单的JavaScript函数做到这一点。

超文本标记语言

 <img src="some_image.tiff"
onerror="fallBackImg(this);"
data-src-1="some_image.png"
data-src-2="another_image.jpg">

JavaScript

function fallBackImg(elem){
elem.error = null;
let index = elem.dataset.fallIndex || 1;
elem.src = elem.dataset[`src-${index}`];
elem.dataset.fallIndex = ++index;
}

我觉得这是处理许多备用图像的一种非常轻量级的方式。

如果你想要“HTML only”;那么这个

<img src="some_image.tiff"
onerror="this.error = null;
let i = this.dataset.i || 1;
this.src = this.dataset[`src-${i}`];
this.dataset.i = ++i;"
data-src-1="some_image.png"
data-src-2="another_image.jpg">

3个解决方案:


考虑以下html文件:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
  

<title>Document</title>
</head>
<body>
<img id="imageId">
<script src="setimage.js"></script>
</body>
</html>
< p > 解决方案一: < br > 在html的body标签中引用这段JS代码为
<script src="setimage.js"></script>
并设置SRC路径,第一个是如果有错误,下一个是你希望第一次工作的路径:)

var img = document.getElementById("imageId")
img.onerror = () => {
img.src= "../error.png";
}
img.src= "../correct.webp.png";

解决方案二: < br >

这个解决方案几乎是相同的,相反,您将调用方法,同样是在脚本标记的正文的末尾,但将在那里提供路径。

function setImageWithFallback(mainImgPath, secondaryImgPath) {
var img = document.getElementById("imageId")
img.onerror = () => {
img.src= mainImgPath;
}
img.src= secondaryImgPath;
}
< p > 解决方案三: < br > 如果它只是一张图片,这将是最简单的:)简单地设置onerror在img标签

<img id="imageId" src="../correct.webp.png"
onerror="if (this.src != '../error.png') this.src = '../error.png';">

我正在添加loading="lazy"到img标签。在某些情况下,它是有效的。

这是一个简单的Jquery,为我工作

        $(image).on('error', function(event) {
imgage.attr('src', 'your_image.png');})

反应

<img
src="https://example.com/does_not_exist.png"
onError={(e) => {
e.currentTarget.src = "https://example.com/default.png"
}}
/>