it-swarm.com.ru

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

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

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

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

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

202
William

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

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

231
Xavi

Проверьте свойства 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;
}
211
SLaks

Основываясь на моем понимании спецификация W3C HTML для элемента 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 всегда находится в одном из следующих состояний:

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

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

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

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

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

50
Ajedi32

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

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

18
Kal

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

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

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

Ресурсы

11
Josh Harrison

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

4
Julha

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

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

2
Justin Vincent

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

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

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

Одна вещь, о которой вам нужно знать, это то, что эта функция также будет возвращать 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
}

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

2
data-dan

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

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

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

1
user1018645

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

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

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

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

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

0
Ajay Gupta

У меня было много проблем с полной загрузкой изображения и 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, помогали мне уже более ста раз. За это очень большое спасибо!

0
Scoobeedo Cool