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

268

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

Galilyou
источник
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

Amit Bakle
источник
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 возвращает какую-либо ошибку, пользователь не увидит никаких изменений, и это будет понятно для пользователя.

Эмилиано Барбоза
источник
developer.mozilla.org/en/docs/Web/CSS/…
Эмилиано Барбоза,
Это работает, только если image1 полностью непрозрачен. Если он имеет прозрачность, как это делают большинство изображений значков, тогда image2 просвечивает.
jdunning
14
<style type="text/css">
img {
   background-image: url('/images/default.png')
}
</style>

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

lambacck
источник
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.

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

Obie
источник
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>
bapho
источник
это здорово! знать о пропавшей поддержке браузера caniuse.com/#feat=picture . рассмотрите возможность использования полифилла или другого решения, если вам нужна поддержка старых браузеров, таких как IE11.
Хинрих
7

angular2:

<img src="{{foo.url}}" onerror="this.src='path/to/altimg.png'">
user3601578
источник
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

eithed
источник
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 изображения

Xofo
источник
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;
}

Я чувствую, что это довольно легкий способ обработки многих резервных изображений.

Rager
источник
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

SunSay
источник
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');
  }
Suhail
источник