Ввод изображения по умолчанию в случае, если атрибут src html <img> недопустим?


268

Есть ли способ отобразить изображение по умолчанию в <img>теге HTML , если srcатрибут недействителен (используется только HTML)? Если нет, то каким был бы ваш легкий способ обойти это?


3
У HTML нет отступления для битых изображений. Вам нужно будет использовать JavaScript, чтобы найти неработающие изображения и изменить их атрибут src.
блиц

2
@Blixt - Что, если ваш клиент MS Outlook или какой-либо другой EMAIL-ридер, и у вас нет Javascript, и опция объекта не работает ... Я предполагаю, что единственным решением является alt / text
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>

Поскольку первое изображение не существует, откроется запасной вариант (спрайты, используемые на этом веб-сайте *). И если вы используете действительно старый браузер, который не поддерживает object, он будет игнорировать этот тег и использовать этот imgтег. Смотрите веб- сайт caniuse для совместимости. Этот элемент широко поддерживается всеми браузерами из IE6 +.

* Если URL-адрес изображения не изменился (снова), в этом случае вы, вероятно, увидите альтернативный текст.


3
Это сработало для меня в IE8 после того, как я вставил DTD для HTML 4.01.
Патрик МакЭлхани

Это не работает, если на несуществующем изображении X-Frame-Optionsустановлено значение SAMEORIGINболее допустимого.
Аттила О.

Это работает, но если ссылка в object.data не является доверенной, она может загружать любые вещи ...
Michael_Scharf

1
Элемент 'img' не может быть вложен в элемент 'object'.
Матеус Миранда

2
@ Матеус Конечно, можно. В HTML4 объект может содержать содержимое потока (почти все, включая img), а в HTML5 он прозрачен, то есть может содержать любой действительный HTML5.
Патрик

318

Это хорошо работает для меня. Может быть, вы хотите использовать JQuery для подключения события.

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

Обновлено с помощью jacquargs error guard

Обновлено: решение только для CSS Недавно я увидел демо Виталия Фридмана - отличное решение 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

30
Чтобы избежать риска бесконечного цикла, просто добавьте тест: <img src = "foo.jpg" onerror = "if (this.src! = 'Error.jog') this.src = 'error.jpg';">
jacquarg

21
Кроме того, вы можете написать:onerror="this.src='error.jpg';this.onerror='';"
Денилсон Са

6
Где в этом jQuery?
Правин Кумар Пурушотаман

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

15

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

Используйте фоновое изображение, которое позволит вам добавить несколько изображений. Мой случай: изображение1 является основным изображением, оно будет получено из какого-то места (браузер выполняет запрос) изображение2 является локальным изображением по умолчанию, которое будет отображаться во время загрузки изображения1. Если image1 возвращает какую-либо ошибку, пользователь не увидит никаких изменений, и это будет понятно для пользователя.



Это работает, только если image1 полностью непрозрачен. Если он имеет прозрачность, как это делают большинство изображений значков, тогда image2 просвечивает.
jdunning

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

Обязательно введите размеры изображения и укажите, хотите ли вы, чтобы изображение было мозаичным или нет.


28
Разве большинство браузеров не показывают изображение «неработающей ссылки», когда изображение не найдено ... В этом случае установка фона не решит проблему.
Джастин Д.

13

Я не думаю, что это возможно, используя только HTML. Однако, используя JavaScript, это должно быть выполнимо. В основном мы перебираем каждое изображение, проверяем, завершено ли оно, и если его естественная ширина равна нулю, это означает, что оно не найдено Вот код:

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которое может быть нулевым, тогда оно будет отображаться как поврежденное. Это запускает выполнение onerrorвыражения атрибута, как описано выше. Вам нужно переопределить srcатрибут, как описано выше, но вам понадобится jQuery для доступа к вашему altSrc. Не удалось заставить его работать с ванильным JavaScript.

Может показаться немного хакерским, но спас день на моем проекте.


11

простой img-элемент не очень гибкий, поэтому я объединил его с картинным элементом. Таким образом, CSS не требуется. при возникновении ошибки все srcset устанавливаются на резервную версию. изображение неработающей ссылки не отображается. он не загружает ненужные версии изображений. элемент picture поддерживает адаптивный дизайн и несколько вариантов отката для типов, которые не поддерживаются браузером.

<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.
Хинрих

7

angular2:

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

1
Хотя это может сработать, я не думаю, что это добавляет какую-либо новую информацию. Часть ошибки - просто ванильный JavaScript, и привязка src уже должна быть известна пользователям Angular
Chic

7

Простое и аккуратное решение, включающее несколько хороших ответов и комментариев.

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

Это даже решает риск бесконечной петли.

Работал на меня.


ИМО, это определенно не выглядит элегантно.
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

Невозможно быть уверенным в бесчисленном количестве клиентов (браузеров), которые попытаются просмотреть вашу страницу. Одним из аспектов, который следует учитывать, является то, что почтовые клиенты являются дефактными веб-браузерами и могут не обрабатывать такие хитрые махинации ...

Таким образом, вы также должны включить alt / text с DEFAULT WIDTH и HEIGHT, как это. Это чисто 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, чтобы ОЧЕНЬ БОЛЬШОЙ ...

Поэтому мой ответ - использовать Javascript с хорошим отступлением от alt / text.

Я также нашел это интересным: как стилизовать атрибут 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.
Джон Уошам

Вы используете JQuery?
mix3d

onError устарела согласно developer.mozilla.org/en-US/docs/Web/HTML/Element/img
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.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);
                });
            }
        };
    }])

Классная идея! Хорошая реализация
З. Кулла,

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-US/docs/Web/HTML/Element/img
comiventor

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 выкинул эту страницу по ключевым словам «image fallback html», но поскольку мне не помогло ни одно из вышеперечисленного, и я искал «поддержку резервирования svg для IE ниже 9», я продолжил поиск, и вот что я нашел:

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

Это может быть не по теме, но это решило мою собственную проблему и могло бы помочь кому-то еще.


0

В дополнение к блестящему ответу Патрика , для тех из вас, кто ищет кроссплатформенное угловое 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

Если вы создали динамический веб-проект и поместили требуемое изображение в 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');
  }
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.