JQuery / JavaScript, чтобы заменить сломанные изображения - PullRequest
513 голосов
/ 18 сентября 2008

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

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

<Ч />

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

Ответы [ 30 ]

3 голосов
/ 02 сентября 2017

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" );

ссылка

3 голосов
/ 18 сентября 2008

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

3 голосов
/ 21 октября 2013

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

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');
        }
    });
}
2 голосов
/ 23 мая 2018

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

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.log(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 -> ,,,,,

2 голосов
/ 20 февраля 2018

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

Подробнее о .error ()

$('img').on('error', function (e) {
  $(this).attr('src', 'broken.png');
});
2 голосов
/ 28 июня 2013
;(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/

2 голосов
/ 25 апреля 2014

Это расстраивало меня годами. Мое исправление CSS устанавливает фоновое изображение на img. Когда динамическое изображение src не загружается на передний план, на bg 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;
  -webkit-animation: fadein 1s;
  animation: fadein 1s;                     
}

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

@keyframes fadein {
  0%   { opacity: 0.0; }
  50%  { opacity: 0.5; }
  100% { opacity: 1.0; }
}
1 голос
/ 14 января 2018

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

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

$$("img").forEach(img => {
  if (!img.naturalWidth && !img.naturalHeight) {
    img.src = img.src;
  }
}
1 голос
/ 16 ноября 2017

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

// Replace broken images by a default img
$('img').each(function(){
    if($(this).attr('src') === ''){
      this.src = '/default_feature_image.png';
    }
});
0 голосов
/ 01 февраля 2019

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

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