Проверьте, загружено ли изображение (без ошибок) с помощью jQuery

Я использую JavaScript с библиотекой jQuery для управления миниатюрами изображений, содержащимися в неупорядоченном списке. Когда изображение загружено, оно выполняет одно действие, а при возникновении ошибки - другое. В качестве событий я использую методы jQuery load() и error(). После этих событий я проверяю DOM-элемент image на наличие .complete, чтобы убедиться, что изображение еще не загружено, прежде чем jQuery сможет зарегистрировать события.

Он работает правильно, за исключением случаев, когда происходит ошибка до того, как jQuery может зарегистрировать события. Единственное решение, о котором я могу подумать, - это использовать атрибут img onerror для хранения "флага" где-то глобально (или на самом узле). это говорит о том, что это не удалось, поэтому jQuery может проверить этот "store/node" при проверке .complete.

У кого-нибудь есть лучшее решение?

Изменение: Основные пункты выделены жирным шрифтом и добавлены дополнительные подробности ниже: Я проверяю, завершено ли изображение (оно также загружено) ПОСЛЕ того, как я добавляю на изображение событие загрузки и ошибки. Таким образом, , если изображение было загружено до того, как события были зарегистрированы, я все равно буду знать. Если изображение не загружается после событий, тогда события позаботятся об этом, когда это произойдет. Проблема в том, что я могу легко проверить, загружено ли уже изображение, но не могу сказать, произошла ли ошибка.

Ответы

Ответ 1

Другой вариант - вызвать события onload и/или onerror, создав элемент изображения в памяти и установив его атрибут src в исходный атрибут src исходного изображения. Вот пример того, что я имею в виду:

$("<img/>")
    .on('load', function() { console.log("image loaded correctly"); })
    .on('error', function() { console.log("error loading image"); })
    .attr("src", $(originalImage).attr("src"))
;

Надеюсь, это поможет!

Ответ 2

Проверьте свойства complete и naturalWidth в этом порядке.

https://stereochro.me/ideas/detecting-broken-images-js

function IsImageOk(img) {
    // During the onload event, IE correctly identifies any images that
    // weren’t downloaded as not complete. Others should too. Gecko-based
    // browsers act like NS4 in that they report this incorrectly.
    if (!img.complete) {
        return false;
    }

    // However, they do have two very useful properties: naturalWidth and
    // naturalHeight. These give the true size of the image. If it failed
    // to load, either of these should be zero.
    if (img.naturalWidth === 0) {
        return false;
    }

    // No other way of checking: assume it’s ok.
    return true;
}

Ответ 3

Основываясь на моем понимании Спецификации HTML W3C для элемента img, вы должны сделать это, используя комбинацию complete и naturalHeight, например:

function imgLoaded(imgElement) {
  return imgElement.complete && imgElement.naturalHeight !== 0;
}

Из спецификации для атрибута complete:

Полный атрибут IDL должен возвращать значение true, если любое из следующих условия верны:

  • Атрибут src опущен.
  • Конечная задача, поставленная в очередь сетевым объектом задачи после загрузки ресурса, была поставлена ​​в очередь.
  • Элемент img полностью доступен.
  • Элемент img сломан.

В противном случае атрибут должен возвращать false.

Таким образом, complete возвращает true, если изображение либо закончило загрузку, либо не загрузилось. Поскольку нам нужен только тот случай, когда изображение успешно загружено, нам нужно проверить атрибут nauturalHeight:

Атрибуты IDL naturalWidth и naturalHeight должны возвращать внутренняя ширина и высота изображения, в пикселях CSS, если изображение, или 0.

И available определяется следующим образом:

Img всегда находится в одном из следующих состояний:

  • Недоступно. Пользовательский агент не получил никаких данных изображения.
  • Частично доступный. Пользовательский агент получил некоторые данные изображения.
  • Полностью доступный. Пользовательский агент получил все данные изображения и, по крайней мере, размеры изображения доступны.
  • Broken. Пользовательский агент получил все данные изображения, которые он может, но он не может даже декодировать изображение достаточно, чтобы получить изображение размеры (например, изображение повреждено, или формат не поддерживается или данные не могут быть получены).

Когда элемент img находится либо в частично доступном состоянии, либо в полностью доступное состояние, считается, что оно доступно.

Итак, если изображение "сломан" (не загружено), оно будет в состоянии разбиения, а не в состоянии, поэтому naturalHeight будет равно 0.

Поэтому проверка imgElement.complete && imgElement.naturalHeight !== 0 должна указать нам, успешно ли загружено изображение.

Подробнее об этом можно узнать в Спецификации HTML W3C для элемента img или на MDN.

Ответ 4

Я пробовал много разных способов, и этот способ работает только для меня

//check all images on the page
$('img').each(function(){
    var img = new Image();
    img.onload = function() {
        console.log($(this).attr('src') + ' - done!');
    }
    img.src = $(this).attr('src');
});

Вы также можете добавить функцию обратного вызова, которая запускается после того, как все изображения будут загружены в DOM и готовы. Это относится и к динамически добавленным изображениям. http://jsfiddle.net/kalmarsh80/nrAPk/

Ответ 5

Используйте imagesLoaded javascript library.

Используется с простым Javascript и как плагин jQuery.

Особенности:

Ресурсы

Ответ 6

Получить информацию из элементов изображения на странице
Тестирование работы на Chrome и Firefox
Работает jsFiddle (откройте консоль, чтобы увидеть результат)

$('img').each(function(){ // selecting all image element on the page

    var img = new Image($(this)); // creating image element

    img.onload = function() { // trigger if the image was loaded
        console.log($(this).attr('src') + ' - done!');
    }

    img.onerror = function() { // trigger if the image wasn't loaded
        console.log($(this).attr('src') + ' - error!');
    }

    img.onAbort = function() { // trigger if the image load was abort
        console.log($(this).attr('src') + ' - abort!');
    }

    img.src = $(this).attr('src'); // pass src to image object

    // log image attributes
    console.log(img.src);
    console.log(img.width);
    console.log(img.height);
    console.log(img.complete);

});

Примечание: я использовал jQuery, я думал, что это может быть достигнуто на полном JavaScript

Я нахожу здесь полезную информацию OpenClassRoom → это французский форум

Ответ 7

Сетевой детектор реального времени - проверьте состояние сети, не обновляя страницу: (это не jquery, но протестировано, а 100% работает: (проверено на Firefox v25.0))

Код:

<script>
 function ImgLoad(myobj){
   var randomNum = Math.round(Math.random() * 10000);
   var oImg=new Image;
   oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
   oImg.onload=function(){alert('Image succesfully loaded!')}
   oImg.onerror=function(){alert('No network connection or image is not available.')}
}
window.onload=ImgLoad();
</script>

<button id="reloadbtn" onclick="ImgLoad();">Again!</button>

Если соединение потеряно, просто нажмите кнопку "Снова".

Обновление 1: Автоматическое обнаружение без обновления страницы:

<script>
     function ImgLoad(myobj){
       var randomNum = Math.round(Math.random() * 10000);
       var oImg=new Image;
       oImg.src="YOUR_IMAGELINK"+"?rand="+randomNum;
       oImg.onload=function(){networkstatus_div.innerHTML="";}
       oImg.onerror=function(){networkstatus_div.innerHTML="Service is not available. Please check your Internet connection!";}
}

networkchecker = window.setInterval(function(){window.onload=ImgLoad()},1000);
</script>

<div id="networkstatus_div"></div>

Ответ 8

Вот как я получил его для работы с перекрестным браузером, используя комбинацию описанных выше методов (мне также нужно было динамически вставлять изображения в dom):

$('#domTarget').html('<img src="" />');

var url = '/some/image/path.png';

$('#domTarget img').load(function(){}).attr('src', url).error(function() {
    if ( isIE ) {
       var thisImg = this;
       setTimeout(function() {
          if ( ! thisImg.complete ) {
             $(thisImg).attr('src', '/web/css/img/picture-broken-url.png');
          }
       },250);
    } else {
       $(this).attr('src', '/web/css/img/picture-broken-url.png');
    }
});

Примечание. Для переменной isIE вам необходимо указать действительное логическое состояние.

Ответ 9

После прочтения интересных решений на этой странице я создал простое в использовании решение, сильно влияющее на сообщения SLaks и Noyo, которые, похоже, работают над довольно недавними версиями (с точки зрения написания) Chrome, IE, Firefox, Safari и Opera (все в Windows). Кроме того, он работал на эмулятор iPhone/iPad, который я использовал.

Одним из основных отличий этого решения от SLaks и Noyo является то, что это решение в основном проверяет свойства naturalWidth и naturalHeight. Я обнаружил, что в текущих версиях браузера эти два свойства предоставляют наиболее полезные и последовательные результаты.

Этот код возвращает TRUE, когда изображение полностью загружено и успешно. Он возвращает FALSE, когда изображение либо еще не загружено полностью, либо не удалось загрузить.

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

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

HTMLImageElement.prototype.isLoaded = function() {

    // See if "naturalWidth" and "naturalHeight" properties are available.
    if (typeof this.naturalWidth == 'number' && typeof this.naturalHeight == 'number')
        return !(this.naturalWidth == 0 && this.naturalHeight == 0);

    // See if "complete" property is available.
    else if (typeof this.complete == 'boolean')
        return this.complete;

    // Fallback behavior: return TRUE.
    else
        return true;

};

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

if (someImgElement.isLoaded()) {
    // YAY! The image loaded
}
else {
    // Image has not loaded yet
}

В комментариях к сообщениям SLaks и Noyo это решение, вероятно, может быть использовано только как одноразовая проверка Safari Mobile, если вы планируете изменить атрибут SRC. Но вы можете обойти это, создав элемент изображения с новым атрибутом SRC вместо изменения атрибута SRC в существующем элементе изображения.

Ответ 10

var isImgLoaded = function(imgSelector){
  return $(imgSelector).prop("complete") && $(imgSelector).prop("naturalWidth") !== 0;
}

//Или как плагин

    $.fn.extend({
      isLoaded: function(){
        return this.prop("complete") && this.prop("naturalWidth") !== 0;
      }
    })

// $(".myImage").isLoaded() 

Ответ 11

Как я понимаю, свойство .complete является нестандартным. Это может быть не универсальным... Я замечаю, что это похоже на работу по-разному в Firefox IE. Я загружаю несколько изображений в javascript, а затем проверяю, завершен ли он. В Firefox это, похоже, отлично работает. В IE это происходит не потому, что изображения загружаются в другой поток. Он работает, только если я поместил задержку между моим назначением на image.src и когда я проверю свойство image.complete.

Использование image.onload и image.onerror тоже не работает для меня, потому что мне нужно передать параметр, чтобы узнать, какое изображение я говорю, когда вызывается функция. Любой способ сделать это, кажется, терпит неудачу, потому что на самом деле он пропускает одну и ту же функцию, а не разные экземпляры одной и той же функции. Таким образом, значение, которое я передаю ему, чтобы идентифицировать изображение, всегда оказывается последним значением в цикле. Я не могу думать об этом.

В Safari и Chrome я вижу, что image.complete true и набор naturalWidth, даже если консоль ошибок показывает 404 для этого изображения... и я намеренно удалил это изображение, чтобы проверить это. Но это хорошо работает для Firefox и IE.

Ответ 12

Этот фрагмент кода помог мне исправить проблемы кэширования браузера:

$("#my_image").on('load', function() {

    console.log("image loaded correctly"); 
}).each(function() {

     if($(this).prop('complete')) $(this).load();
});

Когда кеш браузера отключен, только этот код не работает:

$("#my_image").on('load', function() {
     console.log("image loaded correctly"); 
})

чтобы заставить его работать, вы должны добавить:

.each(function() {
     if($(this).prop('complete')) $(this).load();
});

Ответ 13

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

document.onready = function(e) {
        var imageobj = new Image();
        imageobj.src = document.getElementById('img-id').src;
        if(!imageobj.complete){ 
            alert(imageobj.src+"  -  Not Found");
        }
}

Попробуйте этот

Ответ 14

У меня было много проблем с полной загрузкой изображения и EventListener.

Что бы я ни пытался, результаты были ненадежными.

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

Что я сделал:

                    document.getElementById(currentImgID).addEventListener("load", loadListener1);
                    document.getElementById(currentImgID).addEventListener("load", loadListener2);

                function loadListener1()
                    {
                    // Load again
                    }

                function loadListener2()
                {
                    var btn = document.getElementById("addForm_WithImage"); btn.disabled = false;
                    alert("Image loaded");
                }

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

Все мои головные боли ушли!


Кстати: Вы, ребята, из stackoverflow помогли мне уже более ста раз. Для этого очень большое Спасибо!

Ответ 15

Этот работал хорошо для меня :)

$('.progress-image').each(function(){
    var img = new Image();
    img.onload = function() {
        let imgSrc = $(this).attr('src');
        $('.progress-image').each(function(){
            if($(this).attr('src') == imgSrc){
                console.log($(this).parent().closest('.real-pack').parent().find('.shimmer').fadeOut())
            }
        })
    }
    img.src = $(this).attr('src');
});