web-dev-qa-db-ja.com

setTimeout()は待機していません

私はJavaScriptで秒のカウントダウンを作ろうとしています。

これが私の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>

そして私の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>

ただし、何らかの理由で、タイムアウト時間を待たず、代わりにcountdownをすぐに実行するため、ページを更新するとすぐに「完了」と表示されます。 innerHTML += seconds + " ";を実行すると、45からカウントダウンするため、実際には複数回実行されていることがわかります。なぜタイムアウトがバイパスされるのですか?

30
Mike

setTimeout(countdown(element), 1000);は、その引数を使用して関数を実行し、結果をsetTimeoutに渡します。あなたはそれを望まない。

代わりに、関数を呼び出す無名関数を実行します。

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

これは、setTimeoutが非同期であるためです。これを試して:

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

これにより、関数のカウントダウンが1000ミリ秒後に実行されます。

4
Peter Rasmussen

setTimeoutによって関数に引数を渡したい場合は、次のようにしてください:

setTimeout(countdown, 1000, element);

SetTimeoutの構文は次のとおりです。

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