7

J'essaye d'attendre et d'obtenir un message quand toutes les images dans un tableau ont terminé le chargement (using .complete), par la réponse here. En tant que tel, j'ai mis en place une boucle infinie comme ci-dessous. cependant, lorsque j'exécute ceci, j'obtiens une erreur que checkForAllImagesLoaded() n'est pas définie. Ce code est en cours d'exécution via un bookmarklet, et en tant que tel tout est enveloppé dans une construction de fonction anonyme (comme ci-dessous). Si je redéfinis ma fonction et ma variable en dehors de cette construction, cela fonctionne. Mais cela semble être un mauvais moyen d'écrire un bookmarklet. Comment puis-je résoudre ce problème afin qu'il reconnaisse la fonction après le setTimeout?Fonction qui s'appelle ne fonctionne pas (boucle infinie, 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(); 

})(); 

Répondre

7

Retirez l'appel de fonction, et de prendre les citations. Si vous ne mettez pas les guillemets, setTimeout obtient une référence directe à la fonction qu'il peut invoquer plus tard. Toutefois, si à l'intérieur d'une chaîne telle que "checkForAllImagesLoaded" ou "checkForAllImagesLoaded()", il exécutera le code transmis lorsque le délai d'attente se produit.

À ce moment-là, checkForAllImagesLoaded sera recherché dans l'objet global (fenêtre) mais il n'est pas défini ici, raison pour laquelle vous obtenez l'erreur undefined.

Votre code est enveloppé dans une fonction anonyme auto-appel, et en dehors de celui-ci checkForAllImagesLoaded n'existe pas. Donc passez une référence directe à la fonction dans votre appel setTimeout, au lieu d'une chaîne.

setTimeout(checkForAllImagesLoaded, 20); 

setTimeout peut être appelée soit une fonction (et des arguments optionnels), ou une chaîne contenant du code JavaScript:

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

belle, merci! –

1

Supprimez le() dans l'appel settimeout.

setTimeout('checkForAllImagesLoaded', 20);

+0

Cela ne fonctionnera pas, car le navigateur essaiera d'exécuter l'équivalent de 'eval (« checkForAllImagesLoaded »)' dans la portée globale, où il n'y a pas de nom 'checkForAllImagesLoaded' défini. –

1

Avec votre code, vous définissez un certain nombre de délais d'attente par appel. Vous devriez simplement définir le délai d'attente une fois par appel checkForAllImagesLoaded() et peut-être augmenter la période d'attente (20 millisecondes est juste trop rapide). Par exemple.

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