如何在 JavaScript 中使用 setTimeOut 函数同步倒数计时器

How to synchronize countdown timer with setTimeOut function in JavaScript

我有一个简单的 Bootstrap 页面。这是 children 的一个更大项目的开始,他们必须在其中回答定时测验。此处列出了整个页面。

到目前为止,我的代码有两个问题。第一个问题是定时器与 setTimeOut() 函数不同步。按照预期的运作方式,孩子们将有 45 秒的时间间隔来回答每个问题。倒数计时器将显示在按钮顶部,指示剩余时间。并且,在后台,setTimeOut() 将在 45 秒后终止测验。

我的第一个问题是一旦测验在设计的 45 秒后终止,倒数计时器不会停止,而是将自身重置为另一个 45 秒并继续运行。我希望在这一点上,一旦倒计时结束,下面的“--:--”符号就会出现在计时器的位置,表示没有更多的时间了。

我遇到的第二个问题是,如果 children 在 45 秒间隔内再次单击按钮,我想允许他们重置时间。这适用于倒数计时器,但不适用于 setTimeOut 函数,该函数将始终在 45 秒后终止,并且不会像计时器那样重置。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Untitled Document</title>
<!-- Bootstrap -->
<link href="css/bootstrap-4.2.1.css" rel="stylesheet">
<style>
.TopDivMarg {
    margin-bottom: 50px;
}
</style>
</head>
<body>
<!-- body code goes here -->

<div class="container-fluid">
  <div class="row">
    <div class="col-md-12 TopDivMarg"></div>
  </div>

<!--    Quiz Group  -->

  <div class="row">
    <div class="col-xl-4"></div>
    <div class="col-xl-4">
      <p id="message" class="text-center">[Click on Button to Start Quiz.]</p>
        <p id="time"></p>
    </div>
    <div class="col-xl-4"></div>
  </div>

<!--    Button Group  -->
  <div class="row">
    <div class="col-md-4"></div>
    <div class="col-md-4">
      <button type="button" id="myBtn" class="btn btn-info">Start Quiz</button>
    </div>
    <div class="col-md-4"></div>
  </div>

<script>

  document.getElementById("myBtn").addEventListener("click", function(){
  document.getElementById("message").innerHTML = "What are the colors of the rainbow?";
  errorTimer();
  setTimeout(clearResultF, 45000);
});

// Visible Countdown Timer 
    var timerId;
    function startTimer(duration, display) {

    var timer = duration, minutes, seconds;
    if(timerId != undefined) {
        clearInterval(timerId)
    };

        timerId = setInterval(function () {
        minutes = parseInt(timer / 60, 10)
        seconds = parseInt(timer % 60, 10);

        minutes = minutes < 10 ? "0" + minutes : minutes;
        seconds = seconds < 10 ? "0" + seconds : seconds;

        display.textContent = minutes + ":" + seconds;
        if (--timer < 0) {
            timer = duration;
        };
    }, 1000);
    };

    function errorTimer () {

        var fortyFiveSeconds = 60 * .75,
        display = document.querySelector('#time');
        startTimer(fortyFiveSeconds, display);
        };

    // Reset Timer

      function clearResultF() {
      document.getElementById("message").innerHTML = "[Click on the Button to Start the Quiz.]";
      };

</script>

My first problem is once the quiz is terminated after the 45 seconds as designed, the Countdown Timer does not stop but rather resets itself to another 45 second and keep going

通过设计一个 javascript interval 事件,同时永远持续下去。虽然您只是重置计时器变量,但间隔永远运行这一事实不会发生任何其他变化。为了停止它,您需要清除它(就像您在 startTimer 方法开始时所做的那样。我建议更新此代码:

display.textContent = minutes + ":" + seconds;
if (--timer < 0) {
    timer = duration;
    clearInterval(timerId)
};

This works fine with the Countdown Timer but not with the setTimeOut function which will terminate after 45 seconds all the time and will not reset like the Timer.

和interval事件一样的原因,如果你想让你的超时停止,你需要清除它(所以把它存储在一个变量中,这样当你需要的时候可以清除它的id)。

我可能指出的一个设计问题是超时设置应该发生在 startTimer 方法中,这样您就可以在同一个地方管理所有计时器。我建议进行以下更新:

var timerId;
var countId;

function startTimer(duration, display) {

    var timer = duration, minutes, seconds;

    if(timerId != undefined) {
        clearInterval(timerId)
    };
    if(countId!= undefined) {
        clearTimeout(countId)
    };

    countId = setTimeout(clearResultF, 45000);
    timerId = setInterval(function () { ...