web-dev-qa-db-fra.com

setTimeout () n'attend pas

J'essaie de faire un compte à rebours de secondes avec Javascript.

Voici mon HTML

<div id="ban_container" class="error center">Please wait
        <span id="ban_countdown" style="font-weight:bold">
        45</span>
        seconds before trying again
</div>

Et mon JS:

<script type="text/javascript">
    var seconds = <?php echo $user->getBlockExpiryRemaining(); ?>;

    function countdown(element) {
        var el = document.getElementById(element);

        if (seconds === 0) {
            document.getElementById("ban_container").innerHTML = "done";
            return;
        }
        else {
            el.innerHTML = seconds;
            seconds--;
            setTimeout(countdown(element), 1000);
        }
    }

    countdown('ban_countdown');
</script>

Cependant, pour une raison quelconque, il n'attend pas le délai d'expiration, mais exécute à la place countdown immédiatement de sorte que lorsque je rafraîchis la page, il affiche simplement "terminé" immédiatement. Je sais qu'il est en fait exécuté plusieurs fois parce que si je le fais innerHTML += seconds + " "; il décompte à partir de 45. Pourquoi le délai d'attente est-il contourné?

30
Mike

setTimeout(countdown(element), 1000); exécute votre fonction avec cet argument et passe le résultat dans setTimeout. Tu ne veux pas ça.

Au lieu de cela, exécutez une fonction anonyme qui appelle votre fonction:

setTimeout(function() {
    countdown(el);  // You used `el`, not `element`?
}, 1000);
50
Blender

C'est parce que setTimeout est asynchrone. Essaye ça:

setTimeout(function(){
   countdown('ban_countdown'); //or elemement
}, 1000);

Cela fera exécuter le compte à rebours de la fonction après 1000 millisecondes.

4
Peter Rasmussen

Si vous souhaitez passer un argument à une fonction par setTimeout, essayez ceci:

setTimeout(countdown, 1000, element);

La syntaxe de setTimeout est la suivante:

setTimeout(function,milliseconds,param1,param2,...)
4
Doron Kimia