JQuery / JavaScript для замены битых изображений

У меня есть веб-страница с множеством изображений. Иногда изображение недоступно, поэтому в браузере клиента отображается неработающее изображение.

Как использовать jQuery, чтобы получить набор изображений, отфильтровать его до битых изображений, а затем заменить src?


- Я думал, что будет проще сделать это с помощью jQuery, но оказалось, что намного проще просто использовать решение на чистом JavaScript, то есть то, что предоставлено Prestaul.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
565
0
282 925
31
Перейти к ответу Данный вопрос помечен как решенный

Ответы 31

Ответ принят как подходящий

Обработайте событие onError для изображения, чтобы переназначить его источник с помощью JavaScript:

function imgError(image) {
    image.onerror = "";
    image.src = "/images/noimage.gif";
    return true;
}
<img src = "image.png" onerror = "imgError(this);"/>

Или без функции JavaScript:

<img src = "image.png" onError = "this.onerror=null;this.src='/images/noimage.gif';" />

В следующей таблице совместимости перечислены браузеры, поддерживающие функцию ошибок:

http://www.quirksmode.org/dom/events/error.html

Вероятно, вы захотите очистить значение параметра src onerror перед. В противном случае, если отсутствует noimage.gif, может возникнуть «переполнение стека».

pcorcoran 18.09.2008 21:14

Я думал и надеялся, что мы отходим от встроенных атрибутов для событий javascript ...

redsquare 02.09.2009 10:04

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

Nicole 19.02.2010 00:41

Хороший момент, NickC, насчет разметки, показывающей, что происходит, меня просто передергивает, когда я смотрю на нее: P

SSH This 28.03.2012 01:11

@redsquare, полностью согласен, но это уникальный случай. Inline - единственное место, где вы можете прикрепить слушателя с абсолютной уверенностью, что событие не сработает до того, как ваш слушатель будет присоединен. Если вы сделаете это в конце документа или дождетесь загрузки DOM, вы можете пропустить событие ошибки на некоторых изображениях. Нет смысла прикреплять обработчик ошибок после того, как событие сработало.

Prestaul 05.09.2012 04:40

Это решение не работает для динамических изображений. Однако решение @travis отлично работает с динамическими изображениями.

Mahendra Liya 18.04.2013 23:10

@Mahendra, что ты имеешь в виду под "динамическими изображениями"? Решение travis не работает для изображений, созданных после добавления прослушивателя ошибок ... Это решение работает, если изображения создаются динамически с помощью jQuery. Например. Это работает: jQuery('<img src = "broken.gif" onerror = "imgError(this)" />').appendTo(document.body);

Prestaul 23.04.2013 02:36

@Prestaul: Я тестировал его решение, в котором атрибут src менялся динамически. Однако это решение не сработало в этом случае, но @travis действительно сработал ...

Mahendra Liya 23.04.2013 14:13

@Mahendra, правда. Это решение не сработает, если вы измените src после создания узла. Однако он будет работать, если вы создаете новые теги <img>, а Travis - нет. У каждого метода, безусловно, есть свои плюсы и минусы.

Prestaul 23.04.2013 21:49

@Prestaul ... Просто хотел сказать спасибо за этот ответ. Он мне очень помог. Большое спасибо.

Omiye Jay Jay 29.08.2013 05:02

Встраивание изображения в URL-адрес данных, вероятно, лучше, чем попытка загрузить другое изображение.

Devin Rhode 26.09.2013 13:17

@DevinGRhode, это было бы отличным улучшением. Атрибуту src можно присвоить любое допустимое значение, включая URL-адрес данных.

Prestaul 08.10.2013 00:00

он работает безупречно, но javascript по-прежнему показывает ошибку, старое изображение не найдено, как решить эту ошибку или скрыть, пожалуйста, ответьте в ближайшее время

user2822316 17.10.2013 09:16

@Prestaul Есть ли аналогичный способ загрузки изображений Ajax? Src - это Loader.gif, но исходные данные, содержащие файл изображения, возвращают ошибку 404 Not found.

harishannam 25.03.2014 21:08

Эта реализация работает, но если вы вставили img с innerHTML, она не будет работать, пока вы не вызовете imgError на onerror с префиксом javascript:.

horro 12.11.2014 15:40

почему хром все еще регистрирует 404, если ошибка обрабатывается успешно? stackoverflow.com/questions/30637260/…

Charles Okwuagwu 04.06.2015 10:11

@CharlesO Я ответил в комментарии к вашему другому вопросу. По сути, это не мешает браузеру запрашивать отсутствующие изображения, и нет способа скрыть эту информацию в консоли разработчика. Однако это не должно быть проблемой. Это не означает ошибки в вашей программе, и ваши пользователи просто увидят заменяющее изображение, как вы предполагали. Не позволяйте консоли слишком вас беспокоить.

Prestaul 10.06.2015 00:19

Недавно у меня была такая же проблема с реакцией js, и это решение сработало для меня. Нашел учебник по этому поводу - youtu.be/90P1_xCaim4

Prem 13.01.2019 19:06

Большое спасибо !! за спасение моего лифта.

Muhammad Ayyaz 18.06.2020 22:09

есть ли способ установить это с помощью идентификатора или класса?

Eliot Alderson 27.10.2020 14:36

потому что у меня так много изображений ... я не могу установить ошибку в каждом теге изображения

Eliot Alderson 27.10.2020 14:36

Я считаю, что это то, что вам нужно: jQuery.Preload

Вот пример кода из демонстрации, вы указываете загружаемые и не найденные изображения, и все готово:

jQuery('#images img').preload({
  placeholder:'placeholder.jpg',
  notFound:'notfound.jpg'
});

jQuery.Preload - это плагин, который необходим для использования примера кода.

Dan Lord 18.09.2008 19:35

Да ... это указано в ответе в первой строке.

Nick Craver 18.09.2008 20:03

Спасибо, Ник, похоже, это хорошее решение проблемы, возникшей 8+ лет назад, когда Firefox не показывает замену изображения для неработающих изображений. Плюс вы можете заклеймить эту маленькую вещь ... еще раз спасибо.

klewis 08.08.2014 16:24

Я не уверен, есть ли лучший способ, но я могу придумать, как его получить - вы можете опубликовать Ajax по URL-адресу img и проанализировать ответ, чтобы увидеть, действительно ли изображение вернулось. Если он вернулся как 404 или что-то в этом роде, замените img. Хотя я ожидаю, что это будет довольно медленно.

Вот автономное решение:

$(window).load(function() {
  $('img').each(function() {
    if ( !this.complete
    ||   typeof this.naturalWidth == "undefined"
    ||   this.naturalWidth == 0                  ) {
      // image was broken, replace with your new image
      this.src = 'http://www.tranism.com/weblog/images/broken_ipod.gif';
    }
  });
});

Почти правильно ... правильное изображение в IE по-прежнему будет возвращать (typeof (this.naturalWidth) == "undefined") == true; - Я изменил оператор if на (! This.complete || (! $. Browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)))

Sugendran 19.02.2009 05:42

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

northamerican 30.09.2013 18:51

@Sugendran $.browser устарел и теперь удален, вместо этого используйте обнаружение функций (в этом случае становится сложнее).

lee penkman 04.12.2014 01:20

Автономный, но требует jQuery?

Charlie 06.07.2016 21:12

Это отлично работает, но когда src изображения возвращает 204 No Content, это будет сломанное изображение.

Carson Reinke 04.10.2016 17:59

Я использую встроенный обработчик error:

$("img").error(function () {
    $(this).unbind("error").attr("src", "broken.gif");
});

Редактировать: Метод error() устарел в jquery 1.8 и выше. Вместо этого вы должны использовать .on("error"):

$("img").on("error", function () {
    $(this).attr("src", "broken.gif");
});

Если вы используете эту технику, вы можете использовать метод «one», чтобы избежать необходимости отвязать событие: $ ('img'). One ('error', function () {this.src = 'broken.gif';}) ;

Prestaul 01.04.2011 20:18

+1 А развязать надо? Он прекрасно работает с динамическими изображениями (например, с изображениями, которые могут меняться при наведении курсора), если вы не отвяжете его.

Aximili 05.04.2011 09:27

Я думаю, что если вы не отвяжете его, а ссылка на broken.gif src никогда не загрузится по какой-либо причине, то в браузере могут произойти неприятности.

travis 05.04.2011 19:49

@travis, в какой момент вы бы позвонили? Есть ли способ использовать этот метод и быть уверенным, что ваш обработчик подключается ДО того, как сработает событие ошибки?

Prestaul 05.09.2012 04:43

Вот пример случая, когда ошибка возникает до того, как будет прикреплен обработчик событий: jsfiddle.net/zmpGz/1 Мне искренне любопытно, есть ли надежный способ прикрепить этот обработчик ...

Prestaul 05.09.2012 05:03

@Prestaul Я использовал .bind() вместо .one(), и он отлично работает: jsfiddle.net/zmpGz/4, если не считать помещения глобальной функции в атрибут onerror в самом элементе html, я не уверен, есть ли другой способ сделать это.

travis 05.09.2012 18:04

@travis, я вижу ту же проблему с вашей скрипкой. Если сначала кэшируется сценарий (1.cuzillion.com/bin/resource.cgi?type=js&sleep=4&n=2), тогда вы не заметите проблемы. Попробуйте добавить параметр к URL-адресу скрипта, чтобы очистить кеш (например, & foo = bar), и снова нажмите «Выполнить», и вы увидите только два сообщения об ошибках. Этот сценарий - суть проблемы. Это сценарий, который загружается за 4 секунды, и в течение этого времени появляются первые ошибки изображения, но прослушиватель событий еще не подключен ...

Prestaul 06.09.2012 22:45

Кроме того, я думаю, что вы правы в том, что единственный способ решить проблему - использовать встроенный атрибут onerror ... Я ненавижу это, но именно поэтому я написал свой ответ именно так. :(

Prestaul 06.09.2012 22:48

Иногда изображения добавляются в DOM динамически, и, следовательно, имеет смысл использовать здесь модель делегирования событий.

Eastern Monk 22.12.2012 03:42

Есть ли аналогичный способ для загрузки изображений Ajax? Src - это Loader.gif, но исходные данные, содержащие файл изображения, возвращают ошибку 404 Not found.

harishannam 25.03.2014 21:08

$ ("img"). error (function () не всегда срабатывает - если вместо данных img, например, отправляется документ 404 HTML, этого не произойдет.

Rid Iculous 28.01.2015 02:57

@ RidIculous интересно, я этого не видел. Можете ли вы создать jsbin или jsfiddle, которыми вы могли бы поделиться, чтобы я мог посмотреть?

travis 28.01.2015 07:17

@travis: проверьте это: stackoverflow.com/questions/25438678/…

Rid Iculous 28.01.2015 11:09

$(window).bind('load', function() {
  $('img').each(function() {
    if ( (typeof this.naturalWidth != "undefined" && this.naturalWidth == 0) 
    ||  this.readyState == 'uninitialized'                                  ) {
        $(this).attr('src', 'missing.jpg');
    }
  });
});

Источник: http://www.developria.com/2009/03/jquery-quickie---broken-images.html

Исправлена ​​ошибка, из-за которой onerror не запускался в firefox :) Спасибо.

ram 25.06.2014 17:13

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

Я ограничил его 10 попытками, как если бы оно не было загружено к тому времени, изображение могло отсутствовать на сервере, и функция зашла бы в бесконечный цикл. Я все еще тестирую. Не стесняйтесь его настраивать :)

var retries = 0;
$.imgReload = function() {
    var loaded = 1;

    $("img").each(function() {
        if (!this.complete || typeof this.naturalWidth == "undefined" || this.naturalWidth == 0) {

            var src = $(this).attr("src");
            var date = new Date();
            $(this).attr("src", src + "?v = " + date.getTime()); //slightly change url to prevent loading from cache
            loaded =0;
        }
    });

    retries +=1;
    if (retries < 10) { // If after 10 retries error images are not fixed maybe because they
                        // are not present on server, the recursion will break the loop
        if (loaded == 0) {
            setTimeout('$.imgReload()',4000); // I think 4 seconds is enough to load a small image (<50k) from a slow server
        }
        // All images have been loaded
        else {
            // alert("images loaded");
        }
    }
    // If error images cannot be loaded  after 10 retries
    else {
        // alert("recursion exceeded");
    }
}

jQuery(document).ready(function() {
    setTimeout('$.imgReload()',5000);
});

Хорошая идея с попыткой перезагрузить изображения. Это полезно для изображений, которые загружены / созданы автоматически, и сервер мог не получить / завершить работу при загрузке страницы. Это какое-то оригинальное форматирование. Слишком непоследовательно и, однако, не в моем вкусе ...

Joakim 10.11.2014 16:04

Лучше вызвать, используя

jQuery(window).load(function(){
    $.imgReload();
});

Поскольку использование document.ready не обязательно означает, что загружаются изображения, только HTML. Таким образом, нет необходимости в отложенном звонке.

Если кто-то вроде меня пытается прикрепить событие error к динамическому HTML-тегу img, я хотел бы указать на это, здесь есть одна загвоздка:

Очевидно, события ошибки imgне пузыриться в большинстве браузеров вопреки тому, что говорит стандарт.

Итак, что-то вроде следующего будет не работа:

$(document).on('error', 'img', function () { ... })

Надеюсь, это будет полезно кому-то еще. Хотел бы я видеть это здесь, в этой теме. Но я этого не сделал. Итак, я добавляю это

не сработало. Я загружаю мертвое изображение динамически и добавляю его в dom, и событие «ошибка» не запускается.

vsync 14.06.2014 23:51

то же, что vsync

Roberto Sepúlveda 04.09.2020 17:20

(window.jQuery || window.Zepto).fn.fallback = function (fallback) {
  return this.one('error', function () {
    var self = this;
    this.src = (fallback || 'http://lorempixel.com/$width/$height').replace(
      /$(\w+)/g, function (m, t) { return self[t] || ''; }
    );
  });
};
    

Вы можете передать путь-заполнитель и получить доступ ко всем свойствам из отказавшего объекта изображения через $*:

$('img').fallback('http://dummyimage.com/$widthx$height&text=$src');

http://jsfiddle.net/ARTsinn/Cu4Zn/

Вариант CoffeeScript:

Я сделал это, чтобы исправить проблему с Turbolinks, из-за которой метод .error () иногда возникает в Firefox, даже если изображение действительно существует.

$("img").error ->
  e = $(@).get 0
  $(@).hide() if !$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)

Я решил свою проблему с помощью этих двух простых функций:

function imgExists(imgPath) {
    var http = jQuery.ajax({
                   type:"HEAD",
                   url: imgPath,
                   async: false
               });
    return http.status != 404;
}

function handleImageError() {
    var imgPath;

    $('img').each(function() {
        imgPath = $(this).attr('src');
        if (!imgExists(imgPath)) {
            $(this).attr('src', 'images/noimage.jpg');
        }
    });
}

Вот быстрый и грязный способ заменить все битые изображения, и нет необходимости изменять HTML-код;)

пример кода

    $("img").each(function(){
        var img = $(this);
        var image = new Image();
        image.src = $(img).attr("src");
        var no_image = "https://dummyimage.com/100x100/7080b5/000000&text=No+image";
        if (image.naturalWidth == 0 || image.readyState == 'uninitialized'){
            $(img).unbind("error").attr("src", no_image).css({
                height: $(img).css("height"),
                width: $(img).css("width"),
            });
        }
  });

Это дрянная техника, но она практически гарантирована:

<img onerror = "this.parentNode.removeChild(this);">

Это расстраивало меня годами. Мое исправление CSS устанавливает фоновое изображение на img. Когда динамическое изображение src не загружается на передний план, на панели img отображается заполнитель. Это работает, если ваши изображения имеют размер по умолчанию (например, height, min-height, width и / или min-width).

Вы увидите значок сломанного изображения, но это улучшение. Успешно протестирован до IE9. iOS Safari и Chrome даже не показывают сломанный значок.

.dynamicContainer img {
  background: url('/images/placeholder.png');
  background-size: contain;
}

Добавьте небольшую анимацию, чтобы дать src время для загрузки без мерцания фона. Фон Chrome плавно исчезает, а Safari для настольных ПК - нет.

.dynamicContainer img {
  background: url('/images/placeholder.png');
  background-size: contain;
  animation: fadein 1s;                     
}

@keyframes fadein {
  0%   { opacity: 0.0; }
  50%  { opacity: 0.5; }
  100% { opacity: 1.0; }
}

Используя Ответ престаула, я добавил несколько проверок и предпочитаю использовать способ jQuery.

<img src = "image1.png" onerror = "imgError(this,1);"/>
<img src = "image2.png" onerror = "imgError(this,2);"/>

function imgError(image, type) {
    if (typeof jQuery !== 'undefined') {
       var imgWidth=$(image).attr("width");
       var imgHeight=$(image).attr("height");

        // Type 1 puts a placeholder image
        // Type 2 hides img tag
        if (type == 1) {
            if (typeof imgWidth !== 'undefined' && typeof imgHeight !== 'undefined') {
                $(image).attr("src", "http://lorempixel.com/" + imgWidth + "/" + imgHeight + "/");
            } else {
               $(image).attr("src", "http://lorempixel.com/200/200/");
            }
        } else if (type == 2) {
            $(image).hide();
        }
    }
    return true;
}

Это JavaScript, он должен быть кроссбраузерным и работать без уродливой разметки onerror = "":

var sPathToDefaultImg = 'http://cdn.sstatic.net/stackexchange/img/logos/so/so-icon.png',
    validateImage = function( domImg ) {
        oImg = new Image();
        oImg.onerror = function() {
            domImg.src = sPathToDefaultImg;
        };
        oImg.src = domImg.src;
    },
    aImg = document.getElementsByTagName( 'IMG' ),
    i = aImg.length;

while ( i-- ) {
    validateImage( aImg[i] );
}

КОДЕПЕН:

Если вы вставили свой img с innerHTML, например: $("div").innerHTML = <img src = "wrong-uri">, вы можете загрузить другое изображение, если оно не выполняется, например, следующее:

<script>
    function imgError(img) {
        img.error = "";
        img.src = "valid-uri";
    }
</script>

<img src = "wrong-uri" onerror = "javascript:imgError(this)">

Зачем нужен javascript: _? Поскольку скрипты, внедренные в DOM через теги скриптов в innerHTML, не выполняются в момент их внедрения, поэтому вы должны быть явным.

Для этого вы можете использовать собственную выборку GitHub:

Внешний интерфейс: https://github.com/github/fetch
или для Backend версия Node.js: https://github.com/bitinn/node-fetch

fetch(url)
  .then(function(res) {
    if (res.status == '200') {
      return image;
    } else {
      return placeholder;
    }
  }

Обновлено: этот метод заменит XHR и, предположительно, уже был в Chrome. Для тех, кто будет читать это в будущем, вам может не понадобиться включенная вышеупомянутая библиотека.

Я нашел этот пост, глядя на этот другой пост SO. Ниже приводится копия ответа, который я дал там.

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

Итак, если вы используете React, вы можете сделать что-то вроде приведенного ниже, который был оригиналом ответа, предоставленным Беном Альпертом из команды React здесь.

getInitialState: function(event) {
    return {image: "http://example.com/primary_image.jpg"};
},
handleError: function(event) {
    this.setState({image: "http://example.com/failover_image.jpg"});
},
render: function() {
    return (
        <img onError = {this.handleError} src = {src} />;
    );
}

Я создал рабочий пример, чтобы заменить сломанное изображение с помощью события «onerror». Это может вам помочь.

    //the placeholder image url
    var defaultUrl = "url('https://sadasd/image02.png')";

    $('div').each(function(index, item) {
      var currentUrl = $(item).css("background-image").replace(/^url\(['"](.+)['"]\)/, '');
      $('<img>', {
        src: currentUrl
      }).on("error", function(e) {
        $this = $(this);
        $this.css({
          "background-image": defaultUrl
        })
        e.target.remove()
      }.bind(this))
    })

Хотя OP искал замену SRC, я уверен, что многие люди, задающие этот вопрос, могут захотеть только скрыть сломанное изображение, и в этом случае это простое решение отлично сработал для меня.

Использование встроенного JavaScript:

<img src = "img.jpg" onerror = "this.style.display='none';" />

Использование внешнего JavaScript:

var images = document.querySelectorAll('img');

for (var i = 0; i < images.length; i++) {
  images[i].onerror = function() {
    this.style.display='none';
  }
}
<img src='img.jpg' />

Использование современного внешнего JavaScript:

document.querySelectorAll('img').forEach((img) => {
  img.onerror = function() {
    this.style.display = 'none';
  }
});
<img src='img.jpg' />

См. Поддержку браузером NodeList.forEach и стрелочные функции.

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

pc_ 05.02.2018 02:07

Это явно не работает, если Политика безопасности контента запрещает встроенные скрипты.

isherwood 12.11.2019 17:21

@isherwood Хорошее замечание. Я добавил решение, которое работает через внешний файл JS.

Nathan Arthur 12.11.2019 19:27

лучшее решение здесь

Melvita 08.03.2021 13:22

Вот пример использования объекта HTML5 Image, обернутого JQuery. Вызовите функцию загрузки для URL-адреса основного изображения и, если эта загрузка вызывает ошибку, замените атрибут src изображения на резервный URL-адрес.

function loadImageUseBackupUrlOnError(imgId, primaryUrl, backupUrl) {
    var $img = $('#' + imgId);
    $(new Image()).load().error(function() {
        $img.attr('src', backupUrl);
    }).attr('src', primaryUrl)
}

<img id = "myImage" src = "primary-image-url"/>
<script>
    loadImageUseBackupUrlOnError('myImage','primary-image-url','backup-image-url');
</script>

Чистый JS. Моя задача заключалась в следующем: если изображение 'bl-once.png' пусто -> вставить первое (не имеющее статуса 404) изображение из списка массивов (в текущем каталоге):

<img src = "http://localhost:63342/GetImage/bl-once.png" width = "200" onerror = "replaceEmptyImage.insertImg(this)">

Может быть, его нужно улучшить, но:

var srcToInsertArr = ['empty1.png', 'empty2.png', 'needed.png', 'notActual.png']; // try to insert one by one img from this array
    var path;
    var imgNotFounded = true; // to mark when success

    var replaceEmptyImage = {
        insertImg: function (elem) {

            if (srcToInsertArr.length == 0) { // if there are no more src to try return
                return "no-image.png";
            }
            if (!/undefined/.test(elem.src)) { // remember path
                path = elem.src.split("/").slice(0, -1).join("/"); // "http://localhost:63342/GetImage"
            }
            var url = path + "/" + srcToInsertArr[0];

            srcToInsertArr.splice(0, 1); // tried 1 src

            
                if (imgNotFounded){ // while not success
                    replaceEmptyImage.getImg(url, path, elem); // CALL GET IMAGE
                }
            

        },
        getImg: function (src, path, elem) { // GET IMAGE

            if (src && path && elem) { // src = "http://localhost:63342/GetImage/needed.png"
                
                var pathArr = src.split("/"); // ["http:", "", "localhost:63342", "GetImage", "needed.png"]
                var name = pathArr[pathArr.length - 1]; // "needed.png"

                xhr = new XMLHttpRequest();
                xhr.open('GET', src, true);
                xhr.send();

                xhr.onreadystatechange = function () {

                    if (xhr.status == 200) {
                        elem.src = src; // insert correct src
                        imgNotFounded = false; // mark success
                    }
                    else {
                        console.info(name + " doesn't exist!");
                        elem.onerror();
                    }

                }
            }
        }

    };

Таким образом, он вставит правильный файл «необходимый.png» в мой src или «no-image.png» из текущего каталога.

Я использовал на том же сайте. Это просто идея. Мой реальный код был улучшен ...

Дмитрий Дорогонов 23.06.2017 15:44

jQuery 1.8

// If missing.png is missing, it is replaced by replacement.png
$( "img" )
  .error(function() {
    $( this ).attr( "src", "replacement.png" );
  })
  .attr( "src", "missing.png" );

jQuery 3

// If missing.png is missing, it is replaced by replacement.png
$( "img" )
  .on("error", function() {
    $( this ).attr( "src", "replacement.png" );
  })
  .attr( "src", "missing.png" );

ссылка

У меня та же проблема. Этот код хорошо работает в моем случае.

// Replace broken images by a default img
$('img').each(function(){
    if ($(this).attr('src') === ''){
      this.src = '/default_feature_image.png';
    }
});

Иногда использование события error невозможно, например потому что вы пытаетесь сделать что-то на уже загруженной странице, например, когда вы запускаете код через консоль, букмарклет или скрипт, загружаемый асинхронно. В этом случае проверка того, что img.naturalWidth и img.naturalHeight равны 0, похоже, помогает.

Например, вот фрагмент для перезагрузки всех битых изображений из консоли:

$$("img").forEach(img => {
  if (!img.naturalWidth && !img.naturalHeight) {
    img.src = img.src;
  }
}

Если изображение не может быть загружено (например, потому что оно отсутствует по указанному URL-адресу), URL-адрес изображения будет изменен на значение по умолчанию,

Подробнее о .ошибка()

$('img').on('error', function (e) {
  $(this).attr('src', 'broken.png');
});

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

img {
  width: 100px;
  height: 100px;
}
<script>
  window.addEventListener('error', windowErrorCb, {
    capture: true
  }, true)

  function windowErrorCb(event) {
    let target = event.target
    let isImg = target.tagName.toLowerCase() === 'img'
    if (isImg) {
      imgErrorCb()
      return
    }

    function imgErrorCb() {
      let isImgErrorHandled = target.hasAttribute('data-src-error')
      if (!isImgErrorHandled) {
        target.setAttribute('data-src-error', 'handled')
        target.src = 'backup.png'
      } else {
        //anything you want to do
        console.info(target.alt, 'both origin and backup image fail to load!');
      }
    }
  }
</script>
<img id = "img" src = "error1.png" alt = "error1">
<img id = "img" src = "error2.png" alt = "error2">
<img id = "img" src = "https://i.stack.imgur.com/ZXCE2.jpg" alt = "avatar">

Дело в том :

  1. Поместите код в head и выполните его как первый встроенный скрипт. Таким образом, он будет отслеживать ошибки, возникающие после сценария.

  2. Используйте захват событий, чтобы поймать ошибки, особенно для тех событий, которые не всплывают.

  3. Используйте делегирование событий, которое позволяет избежать привязки событий к каждому изображению.

  4. Дайте элементу ошибки img атрибут после присвоения им backup.png, чтобы избежать исчезновения backup.png и последующего бесконечного цикла, как показано ниже:

img error-> backup.png-> error-> backup.png-> error -> ,,,,,

Это, безусловно, лучший ответ. Единственное, что я бы посоветовал, - это использовать let isImgErrorHandled = target.src === 'backup.png';, поскольку он немного упрощает.

Sabo 28.11.2019 19:25

@Sabo, есть небольшая проблема, потому что путь src может не совпадать с путем, который я назначил. Например, target.src='backup.png', но в следующий раз console.info(target.src) может быть не backup.png.

xianshenglu 29.11.2019 08:19

Я обнаружил, что это работает лучше всего: если какое-либо изображение не загружается в первый раз, оно полностью удаляется из DOM. Выполнение console.clear() сохраняет окно консоли чистым, поскольку ошибки 404 не могут быть пропущены с помощью блоков try / catch.

$('img').one('error', function(err) {
    // console.info(JSON.stringify(err, null, 4))
    $(this).remove()
    console.clear()
})

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

lazyload();

var errorURL = "https://example.com/thisimageexist.png";

$(document).ready(function () {
  $('[data-src]').on("error", function () {
    $(this).attr('src', errorURL);
  });
});

Другие вопросы по теме