使用vanilla JavaScript倒计时

时间:2016-11-15 18:13:08

标签: javascript countdown

我的网页上有textarea和3 buttonstextarea收到一个号码。第一个button从数字开始coutdown到0,延迟输出(每秒一个数字,所以如果N是10,它将花费10秒)。第二个button暂停倒计时,第三个button恢复倒计时(不重新开始)。在执行期间的任何时候按下第一个button将使用textarea中的任何数字重新启动coutdown。这是我到目前为止的代码:

<!DOCTYPE html>
<html>
    <body>
        <h2>Insert a number:</h2>
        <textarea id="input"></textarea>
        <br/>
        <button id="start" onclick="begin()">BEGIN</button>
        <button id="pause" onclick="pause()">PAUSE</button>
        <button id="resume" onclick="resume()">RESUME</button>
        <h1 id="result"></h1>
        <script>
            var isCounting=true,
                input=document.getElementById("input"),
                countSec;
            function begin() {
                countSec=input.value;
                if (isNaN(countSec)) alert("NaN");
                count();
            }
            function pause() {
                isCounting=false;
            }
            function resume() {
                isCounting=true;
                count();
            }
            function count() {
                var i,
                    bck=countSec;
                for (i=0; i<=bck; i++) {
                    document.getElementById("result").innerHTML=countSec;
                    countSec--;
                }
            }
        </script>
    </body>
</html>

有没有办法在countSec--之后停止执行1秒钟?我已经尝试了2个小时用Date对象和setTimeout做一些事情,但我无法弄清楚每次for次迭代后如何暂停

7 个答案:

答案 0 :(得分:1)

如果你需要在每次减去countSec之间有一个延迟,那么我建议你使用setInterval函数。我已按如下方式修改了您的代码:

var isCounting=true,
    input=document.getElementById("input"),
    countSec
    interval;
function begin() {
    countSec=input.value;
    if (isNaN(countSec)) alert("NaN");
    count();
}
function pause() {
    isCounting=false;
    clearInterval(interval);
}
function resume() {
    isCounting=true;
    count();
}
function count() {
    var i,
        bck=countSec;

    document.getElementById("result").innerHTML=bck;               

    interval = setInterval(function() {
        countSec--;
        document.getElementById("result").innerHTML=countSec;               
    }, 1000);
}

具体来说,我创建了一个全局interval变量,它将保留对间隔的引用。我在count()中设置了间隔,然后在间隔的每个刻度处(延迟为1000毫秒)更新#result ID。暂停,我清除间隔。即使其中一些代码没有被使用(比如isCounting),我仍然保留了很多代码;

以下是行动中的代码:https://jsfiddle.net/exex7jh0/

答案 1 :(得分:1)

这听起来像是实现Javascript内置异步间隔操作的完美场景。

您的计时器应以setIntervalhttps://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval)为中心。基本上,你会设置你的间隔来每秒开火,这会增加你的计数器。

要暂停倒计时,您需要使用clearIntervalhttps://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval)。您还可以使用intervalID来确定setInterval计时器是否正在运行。

这些构建块应该让你前进。如果您需要更多信息,请询问。

答案 2 :(得分:1)

这是一个选项:

    <script>
        var input=document.getElementById("input"),
            countSec,
            timer = null;

        function begin() {
            countSec=input.value;
            if (isNaN(countSec)) alert("NaN");
            if( timer === null ) {
                timer = setTimeout( count, 1000 );
            }
        }

        function pause() {
            clearTimeout( timer );
            timer = null;
        }

        function resume() {
            if( timer === null ) {
                timer = setTimeout( count, 1000 );
            }
        }

        function count() {
            if( countSec > 0 ) {
                countSec--;
            }

            document.getElementById("result").innerHTML = countSec;

            if( countSec > 0 ) {
                timer = setTimeout( count, 1000 );
            }
        }
    </script>

当调用begin时,它会在1秒后在count上设置一个计时器。

当调用稍后的count时,它会减少计数器,更新html并安排自己在{1}后1秒后调用(除非 - 当然 - 计数器达到零)

计划任务存储在setTimeout()中,因此可以使用timer取消(请参阅clearTimeout()

要恢复倒计时,请再次致电pause()

当计数器未运行时,

count()设置为timer,并在启动之前进行检查,以确保只有一个计数器正在运行。

答案 3 :(得分:1)

你想要的是count函数包含一个自调用计时器,如下所示:

var timer;

function count() {
    var result = document.getElementById("result");

    step();

    function step() {
        result.innerHTML=countSec;
        countSec--;
        if (countSec > 0) {
            timer = setTimeout(step, 1000);
        }
    }
}

但是知道超时并不真正算上1000ms。如果你想要准确,你将不得不与它开始的时间进行比较。并降低间隔:

var timer,
    start,
    moment,
    input = document.getElementById("input"),
    result = document.getElementById("result");

function begin() {
    var from = ((parseInt(input.value) + 1) * 1000);
    start = Date.now() + from;
    setTimeout(count, 40);
}

function pause() {
    clearTimeout(timer);
}

function resume() {
    start = Date.now() + (moment * 1000);
    count();
}

function count() {
    moment = parseInt((start - Date.now()) / 1000);
    result.innerHTML = moment;
    if (moment > 0) {
        timer = setTimeout(count, 200);
    }
}

答案 4 :(得分:1)

我认为大多数解决方案已经回答了你的问题。在解决方案中包含间隔操作是一个更好的主意,因为这样更容易并且JS已经提供了它。

  • 也是分离JS和HTML的更好主意。 (通过避免内联事件处理程序)

<强> HTML

<h2>Insert a number:</h2>
<textarea id="input"></textarea>
<br/>
<button id="start">BEGIN</button>
<button id="pause">PAUSE</button>
<button id="resume">RESUME</button>
<h1 id="result"></h1>

<强> JS

// Bind the click events
document.getElementById('start').addEventListener('click', begin);
document.getElementById('pause').addEventListener('click', pause);
document.getElementById('resume').addEventListener('click', resume);

var input = document.getElementById("input");
var countSec;
var timer;

function begin() {
  debugger;
  countSec = input.value;
  if (isNaN(countSec)) alert("NaN");
  count();
  enableTimer();
}

function pause() {
  clearInterval(timer);
}

function resume() {
  enableTimer();
}

function count() {
  if (countSec >= 0) {
    document.getElementById("result").innerHTML = countSec;
  } else {
    clearInterval(timer);
  }
  countSec--;
}

// enable the timer again 
function enableTimer() {
   timer = setInterval(function() {
      count();
    }, 1000);
}

<强> JsFiddle

答案 5 :(得分:0)

当计数达到零时,您可以使用setInterval,intervalID和clearInterval

var isCounting = true,
    input = document.getElementById("input"),
    countSec,
    intervalID;

function begin() {
    countSec = +input.value;
    if (isNaN(countSec)) {
        alert("NaN");
        return;
    }
    document.getElementById("result").innerHTML = countSec;
    intervalID = setInterval(count, 1000);
}

function pause() {
    isCounting = false;
}

function resume() {
    isCounting = true;
}

function count() {
    if (countSec === 0) {
        clearInterval(intervalID);
        return;
    }
    if (isCounting) {
        countSec--;
        document.getElementById("result").innerHTML = countSec;
    }
}
<h2>Insert a number:</h2>
<textarea id="input"></textarea><br/>
<button id="start" onclick="begin()">BEGIN</button>
<button id="pause" onclick="pause()">PAUSE</button>
<button id="resume" onclick="resume()">RESUME</button>
<h1 id="result"></h1>

答案 6 :(得分:0)

继承人另一个解决方案

<!DOCTYPE html>
<html>

  <body>
    <h2>Insert a number:</h2>
    <textarea id="input"></textarea>
    <br/>
    <button id="start" onclick="begin()">BEGIN</button>
    <button id="pause" onclick="pause()">PAUSE</button>
    <button id="resume" onclick="resume()">RESUME</button>
    <h1 id="result"></h1>
    <script>
      let isCounting = true;
      let input = document.getElementById("input");
      let countSec = 0;
      let countDownInterval = false;

      function begin() {
        countSec = input.value;
        if (isNaN(countSec)) alert("NaN");
        count();
      }

      function pause() {
        isCounting = false;
      }

      function resume() {
        isCounting = true;
      }

      function count() {
        // Let's check we're doing a restart 
        if (countDownInterval) {
          clearInterval(countDownInterval);
        }

        countDownInterval = setInterval(function() {
          if (isCounting) {
            document.getElementById("result").innerHTML = countSec;
            countSec -= 1;
            // Times up ??
            if (countSec == -1) {
              clearInterval(countDownInterval);
              countDownInterval = null;
            }
          }
        }, 1000);
      }

    </script>
  </body>

</html>

jsfiddle