如果html <img>的src属性无效,是否输入默认图像?


268

<img>万一src属性无效(仅使用HTML),有什么方法可以在HTML 标签中呈现默认图像?如果没有,那么解决该问题的轻量级方法是什么?


3
HTML不会损坏图像。您需要使用JavaScript查找损坏的图像并更改其src属性。
Blixt

2
@Blixt-如果您的客户端是MS Outlook或其他EMAIL阅读器,而您没有Javascript,并且object选项不起作用,该怎么办...我想唯一的解决方法是alt / text
Xofo

Answers:


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>

由于第一个图像不存在,因此将显示后备(此网站上使用的sprites *)。而且,如果您使用的是不支持的非常旧的浏览器,object它将忽略该标签并使用该img标签。有关兼容性,请参见caniuse网站。IE6 +的所有浏览器都广泛支持此元素。

*除非再次更改图片的网址,否则您可能会看到替代文字。


3
在我为HTML 4.01放入了DTD之后,它在IE8中为我工作。
Patrick McElhaney,2009年

如果不存在的图像已X-Frame-Options设置为SAMEORIGIN或更宽松的设置,则此方法不起作用。
Attila O.

它可以工作,但是如果object.data中的链接不受信任,则可以加载所有内容...
Michael_Scharf

1
元素“ img”不能嵌套在元素“ object”内。
Matheus Miranda

2
@Matheus当然可以。在HTML4中,对象可以包含流内容(几乎所有内容,包括img),而在HTML5中,对象是透明的,这意味着它可以包含任何有效的HTML5。
Patrick McElhaney '17

318

这对我来说很好。也许您想使用JQuery挂接事件。

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

更新了提花错误防护

更新:仅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
在我看来。这是更好的答案。这里的怪癖模式承担错误.....对我来说似乎很安全。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';”>
提花

21
另外,您也可以写:onerror="this.src='error.jpg';this.onerror='';"
DenilsonSáMaia'3

6
jQuery在哪里?
Praveen Kumar Purushothaman

64

在Spring in Action 3rd Ed中找到了此解决方案。

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

更新: 这不是仅HTML解决方案... onerror是javascript


3
这很好。这是imgur上的备用图片的更新:<img src =“ a-missing-image.jpg” alt =“” onerror =“ this.src ='http:///i.imgur.com/hfM1J8s.png' “>
arpo 2015年

15

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

使用可添加多个图像的背景图像。我的情况是:image1是主映像,它将从某个位置(浏览器执行请求)获得。image2是在加载image1时显示的默认本地映像。如果image1返回任何类型的错误,则用户将看不到任何更改,这对于用户体验将是干净的



仅当image1是完全不透明的时才有效。如果像大多数图标图像一样具有透明度,则image2将显示出来。
jdunning

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中使用,并且可以完全重用,但是在这种情况下,我更喜欢轻量级的选项。非常感谢:) +1
Galilyou

你救了我一辈子。
Beardminator

12

如果您使用的是Angular / jQuery,则可能会有所帮助...

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

说明

假设其item属性url可能为null,则当该属性为null时,图像将显示为损坏。onerror如上所述,这触发了属性表达式的执行。您需要src如上所述覆盖属性,但是您将需要jQuery来访问altSrc。无法使其与原始JavaScript一起使用。

可能看起来有些不客气,但为我的项目节省了很多时间。


11

一个简单的img元素不是很灵活,所以我将其与一个图片元素结合在一起。这样就不需要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>

这个很棒!请注意缺少浏览器支持caniuse.com/#feat=picture。如果您需要支持IE11等旧版浏览器,请考虑使用polyfill或其他解决方案。
辛里奇

7

angular2:

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

1
尽管这可能有效,但我认为它不会添加任何新信息。onerror部分只是普通的JavaScript,并且Angular用户应该已经知道src绑定
别致

7

简单而整洁的解决方案,其中包含一些好的答案和评论。

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

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

为我工作。


海事组织,这绝对看起来并不优雅。
Script47

1
@ Script47整洁,我重复整洁
Manish kumar

1
不,我也不会说它整洁。更不用说这可能是其他解决方案的重提。
Script47

奇迹般有效!谢谢!
Goehybrid

1
救生员。我不想要优雅,我想要简单和工作。谢谢!
Kit

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

无法确定尝试查看您页面的无数客户(浏览器)。需要考虑的一个方面是电子邮件客户端是事实上的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中使用object标签遇到了问题,但是我想这也将适用于该问题。

您可以进一步将alt /文字设置为非常大...

因此,我的答案是使用具有出色的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.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';" />

3
使用此代码时,我看到Uncaught TypeError: this.attribute is not a function在Chrome 43
约翰Washam

您正在使用jQuery吗?
mix3d

根据developer.mozilla.org/zh-CN/docs/Web/HTML/Element/img弃用onError
comiventor

2

如果您使用的是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);
                });
            }
        };
    }])

好主意!备用图像数组可以很好地实现
Z. Khullah

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

我觉得这是一种处理许多后备图像的非常轻巧的方法。



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

Google在此页面上添加了“图像后备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

如果您已经创建了动态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">

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.