2016-09-17 12 views
5

Gdy obiekt obrazu jest tworzony, może wiedzieć, kiedy jest w pełni załadowany przy użyciu "pełnej" właściwości lub metody "onload", to obraz ten został przetworzony (na przykład zmiana rozmiaru) za pomocą pewnego czasu, który może wynosić kilka sekund. duże pliki.
Jak sprawdzić, kiedy przeglądarka zakończyła się proces obraz po załadowaniu go?
EDYCJA: W przykładach widać opóźnienie między wiadomością "kompletną" a wyglądem obrazu, chcę tego uniknąć.

Przykład ussing "Onload" Metoda:Jak sprawdzić, kiedy przeglądarka zakończy przetwarzanie obrazu po załadowaniu?

var BIGimage; 
 
\t putBIGimage(); 
 
\t function putBIGimage(){ 
 
\t \t BIGimage=document.createElement("IMG"); 
 
\t \t BIGimage.height=200; 
 
\t \t BIGimage.src="http://orig09.deviantart.net/5e53/f/2013/347/f/d/i_don_t_want_to_ever_leave_the_lake_district_by_martinkantauskas-d6xrdch.jpg"; 
 
\t \t BIGimage.onload=function(){waitBIGimage();}; 
 
\t } 
 
\t function waitBIGimage(){ 
 
\t \t \t console.log("Complete."); 
 
\t \t \t document.body.appendChild(BIGimage); 
 
\t }

przykład stosując "kompletna" właściwości:

var BIGimage; 
 
\t putBIGimage(); 
 
\t function putBIGimage(){ 
 
\t \t BIGimage=document.createElement("IMG"); 
 
\t \t BIGimage.height=200; 
 
\t \t BIGimage.src="http://orig09.deviantart.net/5e53/f/2013/347/f/d/i_don_t_want_to_ever_leave_the_lake_district_by_martinkantauskas-d6xrdch.jpg"; 
 
\t \t waitBIGimage(); 
 
\t } 
 
\t function waitBIGimage(){ 
 
\t \t if (!BIGimage.complete){ 
 
\t \t \t console.log("Loading..."); 
 
\t \t \t setTimeout(function(){ 
 
\t \t \t \t waitBIGimage(); 
 
\t \t \t },16); 
 
\t \t } else { 
 
\t \t \t console.log("Complete."); 
 
\t \t \t document.body.appendChild(BIGimage); 
 
\t \t } 
 
\t }

Edycja: Dzięki reakcja @ Kaiido za JA zrobił to rozwiązanie, aby poczekać na proces tworzenia obrazów.

var imagesList=["https://omastewitkowski.files.wordpress.com/2013/07/howard-prairie-lake-oregon-omaste-witkowski-owfotografik-com-2-2.jpg", 
 
\t \t "http://orig03.deviantart.net/7b8d/f/2015/289/0/f/0ffd635880709fb39c2b69f782de9663-d9d9w6l.jpg", 
 
\t \t "http://www.livandiz.com/dpr/Crater%20Lake%20Pano%2016799x5507.JPG"]; 
 
var BIGimages=loadImages(imagesList); 
 
onLoadImages(BIGimages,showImages); 
 

 
function loadImages(listImages){ 
 
\t var image; 
 
\t var list=[]; 
 
\t for (var i=0;i<listImages.length;i++){ 
 
\t \t image=document.createElement("IMG"); 
 
\t \t image.height=200; 
 
\t \t image.src=listImages[i]+"?"+Math.random(); 
 
\t \t list.push(image); 
 
\t } 
 
\t return list; \t \t 
 
} 
 

 
function showImages(){ 
 
\t loading.style.display="none"; 
 
\t for (var i=0; i<BIGimages.length;i++){ 
 
\t \t document.body.appendChild(BIGimages[i]); 
 
\t } 
 
}; 
 

 
function onLoadImages(images,callBack,n) { 
 
\t if (images==undefined) return null; 
 
\t if (callBack==undefined) callBack=function(){}; 
 
\t else if (typeof callBack!="function") return null; 
 
\t var list=[]; 
 
\t if (!Array.isArray(images)){ 
 
\t \t if (typeof images =="string") images=document.getElementById(images); 
 
\t \t if (!images || images.tagName!="IMG") return null; 
 
\t \t list.push(images); 
 
\t } else list=images; 
 
\t if (n==undefined || n<0 || n>=list.length) n=0; 
 
\t for (var i=n; i<list.length; i++){ 
 
\t \t if (!list[i].complete){ 
 
\t \t \t setTimeout(function(){onLoadImages(images,callBack,i);},16); 
 
\t \t \t return false; 
 
\t \t } 
 
\t \t var ctx = document.createElement('canvas').getContext('2d'); 
 
\t \t ctx.drawImage(list[i], 0, 0); 
 
\t } 
 
\t callBack(); 
 
\t return true; 
 
}
<DIV id="loading">Loading some big images...</DIV>

+0

Czy pierwszy przykład nie zwraca oczekiwanego wyniku? – guest271314

+0

Pierwsza metoda jest preferowana - jeśli to nie działa, to robisz coś złego. –

+0

W przykładach widać opóźnienie między wiadomością "kompletną" a pojawieniem się obrazu, chcę tego uniknąć. –

Odpowiedz

3

Oto jeden sposób.

Metoda CanvasContext2D drawImage jest synchroniczna. Przed użyciem tej metody przeglądarka musi całkowicie renderować obraz.

Dzięki temu można go użyć jako metody oczekiwania w metodzie waitBIGimage.

var BIGimage; 
 
putBIGimage(); 
 

 
function putBIGimage() { 
 
    BIGimage = document.createElement("IMG"); 
 
    BIGimage.height = 200; 
 
    BIGimage.src = "http://orig09.deviantart.net/5e53/f/2013/347/f/d/i_don_t_want_to_ever_leave_the_lake_district_by_martinkantauskas-d6xrdch.jpg?" + Math.random(); 
 
    BIGimage.onload = waitBIGimage; 
 
} 
 

 
function waitBIGimage() { 
 
    // only for demo 
 
    // we've got to also log the time since even the console.log method will be blocked during processing 
 
    var start = performance.now(); 
 
    console.log('waiting', start); 
 

 
    // this is all needed 
 
    var ctx = document.createElement('canvas').getContext('2d'); 
 
    ctx.drawImage(this, 0, 0); 
 

 
    // demo only 
 
    var end = performance.now(); 
 
    console.log("Complete.", end); 
 
    console.log(`it took ${end - start}ms`) 
 

 
    // do your stuff 
 
    document.body.appendChild(BIGimage); 
 
}

Na moim Firefox trwa około 1 sekundy do przetwarzania obrazu, podczas gdy na mojej Chrome wydaje się, że obraz jest już przetwarzane, gdy pożary zdarzenia onload.

+0

Dzięki, edytuję moje pytanie z rozwiązaniem, które zrobiłem :) –

+1

@ ArnauCastellví cieszę się, że ci pomogło, ale nie powinieneś polegać na pełnym statusie w ten sposób. Najpierw wykonasz wiele bezużytecznych połączeń z twoją funkcją, a js uzyska siłę z modelu Event. Pełne może być ustawione na true, jeśli obraz nie załadował się, ale nie można go ustalić z tej właściwości (chociaż można sprawdzić właściwość naturalWidth).To, co chcesz osiągnąć, powinno odbywać się poprzez odsłuchiwanie wszystkich obrazów onload i zdarzenia onerror, zwiększanie zmiennej licznika i wywoływanie końcowego wywołania zwrotnego tylko wtedy, gdy licznik osiągnie łączną liczbę obrazów do załadowania. – Kaiido

+0

Cóż, tak, to tylko test koncepcji, wciąż w nim pracuję. Dziękuję :) –

1

Nie ma niezawodny sposób, aby wiedzieć - przeglądarka może nadal wykonywać arbitralny JavaScript lub wykonać wbudowanych funkcji (czyli rozmiaru okna przeglądarki), które mogą bezpośrednio lub pośrednio wpływają na obraz i spowodować, że zostanie on przerysowany lub wydaje się, że nie kończy się na chwilę rysowania.

Możesz przechwycić określone zdarzenia w czasie trwania obrazu, ale ściśle mówiąc "zakończenie" ma miejsce tylko wtedy, gdy okno przeglądarki jest zamknięte.

Powiązane problemy