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


268

Чи є спосіб вивести зображення за замовчуванням у <img>тег HTML , якщо srcатрибут недійсний (використовуючи лише HTML)? Якщо ні, то який би ваш легкий спосіб обійти це?


3
HTML не має резервного копіювання для пошкоджених зображень. Вам потрібно буде використовувати JavaScript, щоб знайти зламані зображення та змінити їх атрибут src.
Blixt

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тег. Див. Веб- сайт каніуси для сумісності. Цей елемент широко підтримується всіма браузерами від IE6 +.

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


3
Це працювало для мене в IE8 після того, як я помістив DTD для HTML 4.01.
Патрік МакЕлхані

Це не працює, якщо для неіснуючого зображення було X-Frame-Optionsвстановлено SAMEORIGINабо більш дозволене налаштування.
Аттіла О.

Вона працює, але якщо посилання в object.data не довіряється, вона може завантажувати всі речі ...
Michael_Scharf

1
Елемент 'img' не може бути вкладений всередині елемента 'object'.
Матей Міранда

2
@Matheus Впевнений, що може. У HTML4 об’єкт може містити потоковий контент (майже все, включаючи img), а в HTML5 він прозорий, тобто він може містити будь-який дійсний HTML5.
Патрік МакЕлхані

318

Це добре працює для мене. Можливо, ви хочете використовувати JQuery, щоб підключити подію.

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

Оновлено захист помилок jacquargs

Оновлено: єдине рішення 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 та gobs CSS. Якщо вам потрібно застосувати різні зображення в різних місцях, просто розрізняйте клас:.my-special-case img:before { ...


3
На мою думку. Це краща відповідь. Ось чудернацькі прийоми приймають onerror ..... мені здається досить безпечним. quirksmode.org/dom/events/error.html#t01
n0nag0n

12
BTW, якщо 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='';"
Denilson Sá Maia

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' ">
арпо

15

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

Використовуйте фонове зображення, яке дозволяє додавати кілька зображень. Мій випадок: image1 є основним зображенням, це отримає місце (браузер, який робить запит) image2 - локальне зображення за замовчуванням, яке відображатиметься під час завантаження image1. Якщо image1 поверне будь-яку помилку, користувач не побачить жодних змін, і це буде чисто для користувачів



Це працює лише в тому випадку, якщо image1 повністю непрозорий. Якщо вона має прозорість, як це робить більшість зображень іконок, то зображення2 відображатиметься наскрізь.
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 не потрібен. коли трапляється помилка, всі серсети встановлюються у резервну версію. зображення зламаного посилання не відображається. він не завантажує непотрібні версії зображень. Елемент зображення підтримує чуйний дизайн та декілька резервних копій для типів, які не підтримуються браузером.

<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

кутовий2:

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

1
Хоча це може спрацювати, я не думаю, що це додає нової інформації. Частина onerror - це просто ванільний JavaScript, а прив'язка src вже повинна бути відома користувачами Angular
Chic

7

Просте і акуратне рішення, що містить кілька хороших відповідей та коментарів.

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

Це навіть вирішує нескінченний ризик циклу.

Працювали для мене.


ІМО, це точно не виглядає елегантно.
Сценарій47

1
@ Script47 його акуратним, я повторюю акуратним
Маніш Кумар

1
Ні, я б не сказав, що це також акуратно. Не кажучи вже про те, що це, мабуть, переоцінка інших рішень.
Сценарій47

Працює як шарм! Дякую!
Гегібрид

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

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

В такому випадку слід ТАКОЖ включати альт / текст із 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, але я думаю, що це стосується і цього.

Ви можете надалі стилю альт / текст бути ДУЖЕ ВЕЛИКО ...

Тому моя відповідь - це використання 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.
Джон Вашам

Ви використовуєте jQuery?
mix3d

onError застарілий відповідно до developer.mozilla.org/en-US/docs/Web/HTML/Element/img
комiвітор

2

Якщо ви використовуєте 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.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;
}

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


onError застарілий відповідно до developer.mozilla.org/en-US/docs/Web/HTML/Element/img
комiвітор

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 image image backback", але оскільки мені не допомогло нічого вищезазначеного, і я шукав "підтримку 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.