Sprawdź, czy obraz jest wczytany (bez błędów) w JavaScript

Używam JavaScript z biblioteką jQuery do manipulowania miniaturami obrazów zawartymi w nieuporządkowanej liście. Gdy obraz jest ładowany, robi jedną rzecz, gdy wystąpi błąd, robi coś innego. Jako zdarzenia używam metod jQuery load () I error (). Po tych zdarzeniach sprawdzam element Dom obrazu dla .Zakończ, aby upewnić się, że obraz nie został jeszcze załadowany, zanim jQuery zarejestruje zdarzenia.

Działa poprawnie, chyba że wystąpi błąd przed jQuery może rejestrować zdarzenia. jedynym rozwiązaniem, jakie przychodzi mi do głowy, jest użycie atrybutu img onerror do przechowywania "flagi" gdzieś globalnie (lub na samym węźle), która mówi, że się nie powiodła, więc jQuery może sprawdzić ten " store / node "podczas sprawdzania.kompletna.

Ktoś ma lepsze rozwiązanie?

Edit: pogrubiono główne punkty i dodano dodatkowe szczegóły poniżej: Sprawdzam, czy obraz jest kompletny (aka loaded) po dodaniu zdarzenia load I error na obrazie. W ten sposób, jeśli obraz został załadowany, zanim wydarzenia zostały zarejestrowane, nadal będę wiedział. Jeśli obraz nie zostanie załadowany po zdarzeniach, wtedy zdarzenia zajmą się nim, gdy to nastąpi. Problem polega na tym, że mogę łatwo sprawdzić, czy obraz jest już załadowany, ale nie mogę stwierdzić, czy zamiast tego wystąpił błąd.

Author: William, 2009-12-30

14 answers

Inną opcją jest wywołanie zdarzeń onload i/lub onerror poprzez utworzenie elementu obrazu w pamięci i ustawienie jego atrybutu src na oryginalny atrybut src oryginalnego obrazu. Oto przykład tego, co mam na myśli:

$("<img/>")
    .on('load', function() { console.log("image loaded correctly"); })
    .on('error', function() { console.log("error loading image"); })
    .attr("src", $(originalImage).attr("src"))
;
Mam nadzieję, że to pomoże!
 223
Author: Xavi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-16 12:09:24

Sprawdź właściwości complete i naturalWidth w tej kolejności.

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;
}
 199
Author: SLaks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-11 20:51:09

Bazując na moim zrozumieniu specyfikacji HTML W3C dla elementu img , powinieneś być w stanie to zrobić używając kombinacji complete oraz naturalHeight atrybuty, jak tak:

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

Ze spec dla complete atrybut:

Atrybut IDL complete musi zwracać true, Jeśli którykolwiek z poniższych warunki są prawdziwe:

  • atrybut src jest pominięty.
  • ostatnie zadanie, które jest w kolejce przez źródło zadań sieciowych po pobraniu zasobu został ustawiony w kolejce.
  • element img jest całkowicie dostępny.
  • element img jest uszkodzony.

W przeciwnym razie atrybut musi zwracać false.

Więc zasadniczo, complete zwraca true, jeśli obraz zakończył Ładowanie lub nie został załadowany. Ponieważ chcemy tylko przypadek, w którym obraz pomyślnie załadowany musimy sprawdzić nauturalHeight atrybut również:

Atrybuty IDL naturalWidth i naturalHeight muszą zwracać wewnętrzna szerokość i wysokość obrazu, w pikselach CSS, jeśli obraz jest dostępny, albo 0.

I available jest zdefiniowane tak:

Img jest zawsze w jednym z następujących stanów:

  • niedostępny - agent użytkownika nie uzyskał żadnych danych obrazu.
  • częściowo dostępne - agent użytkownika uzyskał część danych obrazu.
  • całkowicie dostępne - agent użytkownika uzyskał wszystkie dane obrazu i przynajmniej dostępne są wymiary obrazu.
  • Broken - agent użytkownika uzyskał wszystkie dane obrazu, które może, ale nie może nawet dekodować obrazu na tyle, aby uzyskać obraz wymiary (np. obraz jest uszkodzony lub format nie jest obsługiwane, lub nie można było uzyskać żadnych danych).

Gdy element img jest albo w stanie częściowo dostępnym, albo w całkowicie dostępny stan, mówi się, że jest dostępny.

Więc jeśli obraz jest "uszkodzony" (nie udało się załadować), to będzie w stanie uszkodzonym, a nie w stanie dostępnym, więc naturalHeight będzie 0.

Dlatego sprawdzenie {[11] } powinno nam powiedzieć, czy obraz został pomyślnie załadowany.

Możesz przeczytać więcej na ten temat w specyfikacji HTML W3C dla img elementu , lub na MDN.

 47
Author: Ajedi32,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-25 14:20:44

Próbowałem na wiele różnych sposobów i tylko ten sposób działa dla mnie

//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');
});

Można również dodać funkcję wywołania zwrotnego uruchamianą po załadowaniu wszystkich obrazów w DOM i gotowe. Dotyczy to również dynamicznie dodawanych obrazów. http://jsfiddle.net/kalmarsh80/nrAPk/

 16
Author: Kal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-04 22:44:38
 11
Author: Josh Harrison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:39

Detektor sieci w czasie rzeczywistym-sprawdzanie stanu sieci bez odświeżania strony: (nie jest to jquery, ale testowane, i 100% działa: (testowane na Firefoksie v25.0))

Kod:

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

Jeśli połączenie utracone wystarczy nacisnąć przycisk ponownie.

Update 1: Automatyczne wykrywanie bez odświeżania strony:

<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
Author: Jenei Tamás,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-16 15:11:04

Pobieranie informacji z elementów graficznych na stronie
Test pracy na Chrome i Firefox
Working jsFiddle (otwórz konsolę, aby zobaczyć wynik)

$('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);

});

Uwaga: użyłem jQuery , myślałem, że można to zrobić na pełnym javascript

Dobre informacje znajduję tutaj OpenClassRoom -- > to jest forum Francuskie

 3
Author: Julha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-20 00:52:27

W ten sposób dostałem go do pracy w przeglądarce za pomocą kombinacji powyższych metod (musiałem też dynamicznie wstawiać obrazy do 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');
    }
});

Uwaga: musisz podać poprawny stan logiczny dla zmiennej isIE.

 2
Author: Justin Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-30 19:20:12

Po zapoznaniu się z ciekawymi rozwiązaniami na tej stronie, stworzyłem łatwe w użyciu rozwiązanie, pod dużym wpływem postu Slaksa i Noyo, które wydaje się pracować nad całkiem najnowszymi wersjami (jak pisanie) Chrome, IE, Firefox, Safari i opery (wszystkie na Windows). Działał również na emulatorze iPhone/iPad, którego używałem.

Jedną z głównych różnic między tym rozwiązaniem a Slaksem i postem Noyo jest to, że rozwiązanie to sprawdza głównie właściwości naturalWidth i naturalHeight. Znalazłem to w obecne wersje przeglądarki, te dwie właściwości wydają się zapewniać najbardziej pomocne i spójne wyniki.

Ten kod zwraca TRUE, gdy obraz został załadowany w pełni i pomyślnie. Zwraca wartość FALSE, gdy obraz nie został jeszcze w pełni załadowany lub nie został załadowany.

Jedną z rzeczy, o której musisz pamiętać, jest to, że funkcja ta zwróci również FALSE, jeśli obraz jest obrazem 0x0 pikseli. Ale te obrazy są dość rzadkie i nie mogę wymyślić bardzo przydatnego przypadku, w którym chciałbym sprawdzić, czy obraz o wymiarach 0x0 pikseli już się załadował:)

Najpierw dołączamy nową funkcję o nazwie "isLoaded" do prototypu HTMLImageElement, tak aby funkcja mogła być używana na dowolnym elemencie obrazu.

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;

};

Następnie, za każdym razem, gdy musimy sprawdzić stan ładowania obrazu, po prostu wywołujemy funkcję "isLoaded".

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

Za komentarz giorgiana do postu Slaksa i Noyo, To rozwiązanie może być wykorzystane tylko jako jednorazowa kontrola na Safari Mobile, jeśli planujesz zmiana atrybutu SRC. Można jednak obejść to, tworząc element obrazu z nowym atrybutem SRC zamiast zmieniać atrybut SRC w istniejącym elemencie obrazu.

 2
Author: data-dan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-28 17:53:58

Jak rozumiem .kompletna nieruchomość jest niestandardowa. To może nie być uniwersalne... Zauważyłem, że w Firefoksie działa inaczej. Ładuję kilka obrazów w javascript, a następnie sprawdzam, czy są kompletne. W Firefoksie wydaje się to działać świetnie. W IE tak nie jest, ponieważ obrazy wydają się ładować w innym wątku. To działa tylko wtedy, gdy umieszczę opóźnienie między moim zadaniem do obrazu.src i kiedy sprawdzam obraz.kompletna własność.

Używanie obrazu.onload i obraz.onerror też nie działa dla mnie, ponieważ muszę przekazać parametr, aby wiedzieć, o którym obrazie mówię, gdy funkcja jest wywoływana. Każdy sposób wykonania tego wydaje się zawodzić, ponieważ faktycznie wydaje się przekazać tę samą funkcję, a nie różne instancje tej samej funkcji. Tak więc wartość, którą przekazuję do niej, aby zidentyfikować obraz, zawsze kończy się jako ostatnia wartość w pętli. Nie mogę wymyślić żadnego sposobu na obejście tego problemu.

Na Safari i Chrome widzę obrazek.complete true i naturalWidth ustawione nawet wtedy, gdy konsola błędów pokazuje 404 dla tego obrazu... celowo usunąłem Ten obraz, żeby to przetestować. Ale powyższe działa dobrze dla Firefoksa i IE.

 1
Author: user1018645,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-28 18:07:12

Używając tego kodu JavaScript możesz sprawdzić, czy obrazek został poprawnie załadowany, czy nie.

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

Wypróbuj to

 0
Author: Ajay Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 11:53:43

Miałem wiele problemów z całkowitym załadowaniem obrazu i EventListener.

Cokolwiek próbowałem, wyniki nie były wiarygodne.

Ale potem znalazłem rozwiązanie. Technicznie nie jest to miłe, ale teraz nigdy nie miałem nieudanego obciążenia obrazu.

Co zrobiłem:

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

Zamiast ładować obraz raz, po prostu Ładuję go drugi raz bezpośrednio po pierwszym raz i oba biegają przez eventhandler.

Wszystkie moje bóle głowy zniknęły!

By the way: Wy ze stackoverflow pomogliście mi już ponad sto razy. Za to bardzo wielkie dziękuję!

 0
Author: Scoobeedo Cool,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-27 06:36:27

Ten fragment kodu pomógł mi rozwiązać problemy z buforowaniem przeglądarki:

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

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

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

Gdy pamięć podręczna przeglądarki jest wyłączona, tylko ten kod nie działa:

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

Aby to działało musisz dodać:

.each(function() {
     if($(this).prop('complete')) $(this).load();
});
 0
Author: Frank,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 12:52:05
var isImgLoaded = function(imgSelector){
  return $(imgSelector).prop("complete") && $(imgSelector).prop("naturalWidth") !== 0;
}

/ / lub jako Plugin

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

// $(".myImage").isLoaded() 
 0
Author: KhaledDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-25 08:16:25