7

Ich versuche zu warten und dann eine Nachricht zu erhalten, wenn alle Bilder in einem Array geladen haben (mit .complete), pro Antwort here. Als solche richte ich eine Endlosschleife wie die folgende ein. Wenn ich das ausführe, bekomme ich einen Fehler, dass checkForAllImagesLoaded() nicht definiert ist. Dieser Code wird durch ein Bookmarklet ausgeführt und ist daher in einem anonymen Funktionskonstrukt verpackt (siehe unten). Wenn ich meine Funktion und Variable außerhalb dieses Konstrukts neu definiere, funktioniert es. Aber das scheint ein schlechter Weg zu sein, ein Bookmarklet zu schreiben. Wie kann ich das beheben, damit es die Funktion nach dem setTimeout noch erkennt?Funktion ruft selbst nicht funktioniert (Endlosschleife, Javascript)

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

})(); 

Antwort

7

den Funktionsaufruf, entfernen und die Zitate herausnehmen. Wenn Sie die Anführungszeichen nicht eingeben, erhält setTimeout einen direkten Verweis auf die Funktion, die später aufgerufen werden kann. Wenn es sich jedoch in einer Zeichenfolge wie "checkForAllImagesLoaded" oder "checkForAllImagesLoaded()" befindet, wird es den Code ausführen, der übergeben wird, wenn das Zeitlimit auftritt.

Zu dieser Zeit wird checkForAllImagesLoaded im globalen Objekt (Fenster) gesucht werden, aber es ist nicht dort definiert, Grund dafür, warum Sie den Fehler erhalten.

Ihr Code ist in eine selbstanrufende anonyme Funktion eingeschlossen, und außerhalb davon checkForAllImagesLoaded ist nicht vorhanden. Übergeben Sie also einen direkten Verweis auf die Funktion in Ihrem setTimeout-Aufruf anstelle einer Zeichenfolge.

setTimeout(checkForAllImagesLoaded, 20); 

setTimeout kann entweder mit einer Funktion (und optionalen Argumenten) oder ein String mit JavaScript-Code aufgerufen werden:

var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]); 
var timeoutID = window.setTimeout(code, delay); 
+0

schön, danke! –

1

Entfernen Sie die() im settimeout-Aufruf.

setTimeout('checkForAllImagesLoaded', 20);

+0

, die nicht funktionieren, da der Browser (‚checkForAllImagesLoaded‘) 'im globalen Bereich werden versuchen, das Äquivalent von' eval ausführen, wo es keinen Namen 'checkForAllImagesLoaded' definiert. –

1

mit Ihrem Code, stellen Sie eine Reihe von Timeouts pro Anruf. Sie sollten das Timeout nur einmal pro checkForAllImagesLoaded() Anruf setzen und vielleicht die Wartezeit erhöhen (20 Millisekunden ist einfach zu schnell). Z.B.

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