8

ここでの回答に従って、配列内のすべての画像の読み込みが完了したときに(.completeを使用して)待機してからメッセージを取得しようとしています。そのため、以下のような無限ループを設定しました。ただし、これを実行すると、checkForAllImagesLoaded()が定義されていないというエラーが発生します。このコードはブックマークレットを介して実行されているため、すべて匿名関数構造にラップされています(以下を参照)。その構造の外で関数と変数を再定義すると、機能します。しかし、それはブックマークレットを書くための悪い方法のようです。setTimeout後も関数を認識できるように、これを修正するにはどうすればよいですか?

(function() {

    //var images = array of images that have started loading

    function checkForAllImagesLoaded(){
        for (var i = 0; i < images.length; i++) {
            if (!images[i].complete) {
               setTimeout('checkForAllImagesLoaded()', 20);
               return;
            }
        }
    }

    checkForAllImagesLoaded();

})();
4

3 に答える 3

8

関数呼び出しを削除し、引用符を取り出します。引用符を付けない場合は、setTimeout後で呼び出すことができる関数への直接参照を取得します。ただし、"checkForAllImagesLoaded"またはなどの文字列内にある"checkForAllImagesLoaded()"場合は、タイムアウトが発生したときに渡されたコードを実行します。

そのとき、はグローバルオブジェクト(ウィンドウ)で検索されますが、そこでは定義されていません。これがエラーが発生checkForAllImagesLoadedする理由です。undefined

コードは自己呼び出し無名関数にラップされており、その外にcheckForAllImagesLoadedは存在しません。したがって、文字列ではなく、setTimeout呼び出しで関数への直接参照を渡します。

setTimeout(checkForAllImagesLoaded, 20);

setTimeout関数(およびオプションの引数)、またはJavaScriptコードを含む文字列のいずれかを使用して呼び出すことができます。

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
var timeoutID = window.setTimeout(code, delay);
于 2010-06-30T01:34:45.353 に答える
1

settimeout呼び出しの()を削除します。

setTimeout('checkForAllImagesLoaded', 20);

于 2010-06-30T01:30:54.303 に答える
1

コードを使用して、呼び出しごとにタイムアウトの数を設定します。呼び出しごとに1回タイムアウトを設定しcheckForAllImagesLoaded()、待機期間を長くする必要があります(20ミリ秒は速すぎます)。例えば

function checkForAllImagesLoaded() {
  var allComplete=true;
  var i=0;

  while (i<images.length && allComplete) {
    allComplete=images[i++].complete;
  }

  if (!allComplete) { // Any incomplete images?
    setTimeout('checkForAllImagesLoaded()',1000); // Wait a second!
  }
}
于 2010-06-30T01:52:44.517 に答える