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

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

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

<Ч />

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

Ответы [ 30 ]

5 голосов
/ 19 августа 2014

Это 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] );
}

CODEPEN:

5 голосов
/ 02 мая 2016

Вы можете использовать собственную выборку 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;
    }
  }

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

4 голосов
/ 18 июля 2013

CoffeeScript вариант:

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

$("img").error ->
  e = $(@).get 0
  $(@).hide() if !$.browser.msie && (typeof this.naturalWidth == "undefined" || this.naturalWidth == 0)
4 голосов
/ 24 декабря 2011

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

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

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

4 голосов
/ 29 июня 2014

Используя ответ Престаля , я добавил несколько проверок и предпочитаю использовать способ 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;
}
4 голосов
/ 04 ноября 2016

Вот пример, использующий объект 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>
4 голосов
/ 07 апреля 2017

Чистый 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.log(name + " doesn't exist!");
                        elem.onerror();
                    }

                }
            }
        }

    };

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

4 голосов
/ 01 сентября 2016

Я создал скрипку для замены поврежденного изображения с помощью события "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\(['"](.+)['"]\)/, '$1');
      $('<img>', {
        src: currentUrl
      }).on("error", function(e) {
        $this = $(this);
        $this.css({
          "background-image": defaultUrl
        })
        e.target.remove()
      }.bind(this))
    })
4 голосов
/ 13 июля 2016

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

Я знаю, что это старая ветка, но 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} />;
    );
}
4 голосов
/ 12 ноября 2014

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

...