使用原版倒计时 JavaScript
Countdown using vanilla JavaScript
我的这个网页有一个 textarea
和 3 个 buttons
。 textarea
收到一个数字。第一个 button
开始从数字到 0 的 coutdown,延迟输出(每秒一个数字,所以如果 N 是 10,则需要 10 秒)。第二个 button
暂停倒计时,第三个 button
恢复倒计时(不重新开始)。在执行期间的任何时候按第一个 button
都会重新启动 coutdown,无论数字在 textarea
中是什么。这是我目前的代码:
<!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
迭代后暂停
如果您需要在每次减去 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/
这听起来像是实现 Javascript 的内置异步间隔操作的完美场景。
您的计时器应以 setInterval
( https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval ) 为中心。基本上,您将设置每秒触发一次的时间间隔,这将增加您的计数器。
要暂停倒计时,您需要使用 clearInterval
( https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval )。也可以通过intervalID判断setInterval定时器是否运行
这些构建基块应该可以帮助您前进。如果您需要更多信息,请询问。
这里有一个选项:
<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 秒后用 setTimeout()
调用自身(除非 - 当然 - 计数器达到零)
计划任务存储在 timer
中,因此可以使用 clearTimeout()
取消(参见 pause()
)
要恢复倒计时,只需再次调用 count()
。
当计数器不是 运行 时 timer
设置为 null
并且在启动它之前进行检查以确保只有 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);
}
}
我想大部分的解决方案已经回答了你的问题。在您的解决方案中包含间隔操作是一个更好的主意,因为这更合适并且 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);
}
当计数达到零时,您可以使用 setInterval
, an intervalID and 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>
这是另一个解决方案
<!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>
我的这个网页有一个 textarea
和 3 个 buttons
。 textarea
收到一个数字。第一个 button
开始从数字到 0 的 coutdown,延迟输出(每秒一个数字,所以如果 N 是 10,则需要 10 秒)。第二个 button
暂停倒计时,第三个 button
恢复倒计时(不重新开始)。在执行期间的任何时候按第一个 button
都会重新启动 coutdown,无论数字在 textarea
中是什么。这是我目前的代码:
<!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
迭代后暂停
如果您需要在每次减去 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/
这听起来像是实现 Javascript 的内置异步间隔操作的完美场景。
您的计时器应以 setInterval
( https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval ) 为中心。基本上,您将设置每秒触发一次的时间间隔,这将增加您的计数器。
要暂停倒计时,您需要使用 clearInterval
( https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval )。也可以通过intervalID判断setInterval定时器是否运行
这些构建基块应该可以帮助您前进。如果您需要更多信息,请询问。
这里有一个选项:
<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 秒后用 setTimeout()
调用自身(除非 - 当然 - 计数器达到零)
计划任务存储在 timer
中,因此可以使用 clearTimeout()
取消(参见 pause()
)
要恢复倒计时,只需再次调用 count()
。
timer
设置为 null
并且在启动它之前进行检查以确保只有 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);
}
}
我想大部分的解决方案已经回答了你的问题。在您的解决方案中包含间隔操作是一个更好的主意,因为这更合适并且 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);
}
当计数达到零时,您可以使用 setInterval
, an intervalID and 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>
这是另一个解决方案
<!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>