Проверьте, загружено ли изображение (без ошибок) в JavaScript



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



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



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



изменить: выделено жирным шрифтом основные пункты и добавлена дополнительная деталь ниже:
Я проверяю, завершено ли изображение (aka loaded) после добавления события load и error на изображение. Вот так,если изображение было загружено до регистрации событий, я все равно буду знать. Если изображение не загружается после событий, то событий будет заботиться о нем, когда это произойдет. Проблема в том, что я могу легко проверить, если изображение уже загружено, но я не могу сказать, произошла ли ошибка вместо этого.

1442   14  

14 ответов:

другой вариант-вызвать 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"))
;

надеюсь, что это помогает!

Регистрация 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;
}

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

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

из спецификации для complete:

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

  • src атрибут опущен.
  • конечная задача, поставленная в очередь источником сетевой задачи после извлечения ресурса, поставлена в очередь.
  • элемент img полностью доступен.
  • элемент img сломан.

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

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

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

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

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

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

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

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

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

вы можете прочитать больше об этом в спецификация HTML W3C для img элемент или на MDN.

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

//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/

использовать imagesLoaded библиотека javascript.

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

характеристики:

ресурсы

детектор сети в реальном времени-проверьте состояние сети без обновления страницы: (это не 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>

извлечение информации из элементов изображения на странице
Тест работает на 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 --> это французский форум

вот как я получил его для работы кросс-браузера, используя комбинацию методов выше (мне также нужно было динамически вставлять изображения в 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.

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

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

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

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

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

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
}

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

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

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

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

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

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

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

У меня было много проблем с полной загрузкой изображения и 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");
                }

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

все мои головные боли прошли!


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

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

$("#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();
});
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() 

Comments

    Ничего не найдено.