2016-06-16 58 views
1

JavaScriptで画像を読み込んでいます。このような何か:画像読み込みがJavaScriptで完了するまで待つ

images[0]=new Image(); 
images[0].onload=function(){loaded++;console.log(loaded)}; 
images[0].src="assets/img/image.png"; 

私は、ログを見てみると、私はすべての画像は、各ロードされたイメージを持つ「ロード」変数の値が増加するので、うまくロードされていることがわかります。

しかし、この量が最大に達するまで、実行するアクションを停止したいので、画像を設定した直後に私はしばらくサイクルを置きます。

while(loaded<11){ 
    document.getElementById("test").innerHTML="Loading "+loaded+"/11"; 
    console.log(loaded); 
} 
//Some code here which should only run after everything has been loaded 
//In other words: when the statement in the while cycle becomes false 

しかし、私のブラウザはクラッシュしますが、その間は無限ループに陥っているようです。私がログを確認すると、 "0"が1000回書き込まれ、その後、1から11までの数字が表示されます(実際に画像がロードされることを意味しますが、その間は気にしません。起こる可能性があるよりも)。

私がここで使用しようとしている方法は、この問題を解決する正しい方法ではないと思います。

サイトに必要なすべての資産がロードされるまで、すべてを保留にするにはどうすればよいですか?

+0

条件が真である限り、できるだけ速くサイクルされていますが、 – vlatkokaplan

答えて

3

個人的に私はwhile()を使用するのが嫌い...最も簡単な方法は、イベントリスナーを使用することです。

var img = new Image; 
img.addEventListener("load", function() { 

//Img loaded 

}); 
img.src= e.target.result; 
+0

ありがとうございます!各画像にリスナーを追加し、変数が希望の数に達したかどうかを確認します。最後に開始するイベントもスクリプトの残りの部分を開始します。好奇心のためだけに:イメージにリスナーを追加する場所は重要ですか?ソースを定義した後、または前に?私はそれを前に追加しましたが、どのような違いが生まれるのだろうかと思います。 – Letokteren

+0

私の例は悪いと思う。通常は、ソースをターゲットにする前にイベントリスナーを追加する必要があります。その背後にあるロジックは、エグゼキュータの前にウォッチャーを置くことです。 –

1

Javascriptはシングルスレッドです。つまり、イベントリスナーを追加すると、現在の実行が完了するまでリスナーは実行されません。したがって、イベントに依存するループを開始すると、イベントを終了させることはありません。なぜなら、現在の実行によって実行されないため、イベントは発生しないためです。また、イベントは非同期にコールスタック上に配置されるため、実行がイベント発生率(コールスタックにコールをかける)よりも遅い場合は、ページクラッシュのリスクもあります。これは、間隔がコードの実行に要する時間よりも短い時間に設定されている場合にsetIntervalを使用するとよくある間違いです。決してsetIntervalを使用しないでください。

Javascriptはすぐに2つのことを行うことができないことを覚えておいてください。

リソース監視負荷を処理する最善の方法は、setTimeoutを使用することです。

var allLoaded = false; 
var imgCount = 0; // this counts the loaded images 
// list of images to load 
const imageURLS =["a.jpg","b.jpg","c.jpg","d.jpg","e.jpg"]; 
// array of images 
var images = []; 

const onImageLoad = function(){ imgCount += 1; } // onload event 
// loads an image an puts it on the image array 
const loadImage = function(url){ 
    images.push(new Image()); 
    images[images.length-1].src = url 
    images[images.length-1].onload = onImageLoad; 
} 
const waitForLoaded = function(){ 
    if(imgCount === images.length){ 
     allLoaded = true; // flag that the image have loaded 
    }else{ 
     // display the progress here 
     ... 

     setTimeout(waitForLoaded,100); // try again in 100ms 
    } 
} 

// create the images and set the URLS 
imageURLS.forEach(loadImage); 

setTimeout(waitForLoaded,100); // monitor the image loading 
関連する問題