5

jQuery/JavaScript: Замена битых изображений

31

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

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


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

5 ответ(ов)

0

Вот самостоятельное решение вашей проблемы:

$(window).load(function() {
  $('img').each(function() {
    if ( !this.complete
    ||   typeof this.naturalWidth == "undefined"
    ||   this.naturalWidth == 0                  ) {
      // изображение повреждено, замените его на ваше новое изображение
      this.src = 'http://www.tranism.com/weblog/images/broken_ipod.gif';
    }
  });
});

В этом коде мы используем событие load для окна, чтобы убедиться, что все изображения загружены. Затем, перебираем каждое изображение на странице с помощью $('img').each(). Для каждого изображения проверяем, завершена ли загрузка, определено ли его натуральное ширина и не равно ли оно нулю. Если одно из условий истинно, мы заменяем его на изображение, указывая новый URL.

0

Этот код использует jQuery для проверки наличия изображений на странице. Когда окно полностью загружено (load), он проходит по каждому элементу <img> и проверяет, корректно ли загружены изображения. Если ширина изображения (naturalWidth) равна 0 или состояние загрузки (readyState) равно 'uninitialized', то устанавливается атрибут src на 'missing.jpg', что позволяет заменить отсутствующие изображения на заданное изображение-заглушку.

Вот краткое объяснение каждой части кода:

  1. $(window).bind('load', function() {...}); - эта функция выполняется, когда все элементы окна (включая изображения и другие ресурсы) загружены.
  2. $('img').each(function() {...}); - перебираем каждый элемент <img> на странице.
  3. if ((typeof this.naturalWidth != "undefined" && this.naturalWidth == 0) || this.readyState == 'uninitialized') {...} - проверяем, если:
    • naturalWidth не определён (то есть браузер не поддерживает эту функцию) и равен 0 (значит изображение не загружено),
    • или состояние загрузки изображения не инициализировано.
  4. $(this).attr('src', 'missing.jpg'); - если условие выполняется, заменяем источник изображения на 'missing.jpg'.

Таким образом, данный код позволяет избежать отображения сломанных изображений на веб-странице.

Источник: приведённая ссылка.

0

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

Я ограничил количество попыток до 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()); // небольшое изменение URL, чтобы избежать загрузки из кэша
            loaded = 0;
        }
    });

    retries += 1;
    if (retries < 10) { // Если после 10 попыток изображения так и не загрузились, возможно, их нет на сервере,
                        // что завершит рекурсию
        if (loaded == 0) {
            setTimeout('$.imgReload()', 4000); // Я думаю, что 4 секунды — это достаточно для загрузки небольшого изображения (<50k) с медленного сервера
        }
        // Все изображения загрузились
        else {
            // alert("изображения загружены");
        }
    }
    // Если изображения не загрузились после 10 попыток
    else {
        // alert("превышено количество попыток");
    }
}

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

Не забудьте протестировать скрипт в вашем проекте!

0

Вы можете использовать встроенную функцию fetch от GitHub для этого:

Для фронтенда: https://github.com/github/fetch

или для бэкенда, версия для Node.js: https://github.com/bitinn/node-fetch

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

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

0

Вы правы, что использование $(document).ready() не гарантирует, что все изображения загружены, так как этот обработчик срабатывает, как только DOM полностью загружен, но не дожидается загрузки всех медиафайлов. Поэтому предпочтительно использовать $(window).load(), что позволяет выполнить ваш код только после полной загрузки всех ресурсов страницы, включая изображения.

Вот как это можно сделать:

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

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь