我正在研究一个计时器,经过我在这个论坛得到的一些答案之后,它一直都很顺利。这就是它现在的样子:(只是为了让你明白这一点)
我的代码(请注意,这是一项正在进行中的工作,因此有些内容尚未完成;基本上每个具有alert("workin");
的函数仍未使用。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>WIP</title>
<meta charset="UFT-8">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<script>
$(document).ready(function() {
timerSet(9,12);
timerRun();
});
function timerReset() {
alert("workin");
}
function timerSet(inputMinutes, inputSeconds) {
minutes = inputMinutes;
seconds = inputSeconds;
finalTimeInSeconds = minutes*60 + seconds; //finalTimeInSeconds is the time it takes for the timer to be 00:00 in seconds.
timerPrint();
}
function timerAdd(inputMinutes, inputSeconds) {
alert("workin");
}
function timerSubtract(inputMinutes, inputSeconds) {
setTimeout(function () {
if(minutes > 0 && seconds == 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
timerPrint();
}, 1000);
}
function timerRun() {
timerSubtract();
}
function timerStop() {
alert("workin");
}
function timerPrint() {
displayMinutes = (minutes.toString().length == 2) ? minutes : "0" + minutes; //ternary operator: adds a zero to the beggining
displaySeconds = (seconds.toString().length == 2) ? seconds : "0" + seconds; //of the number if it has only one caracter.
$("#timerText").text(displayMinutes + ":" + displaySeconds);
}
function totalTime() {
var totalTimeInSeconds = minutes*60 + seconds;
return totalTimeInSeconds; //totalTimeInSeconds is the time that the timer now displays in seconds.
}
</script>
</head>
<body>
<div id="timerText">00:00</div>
</body>
</html>
&#13;
所以这是我的问题:在timerRun()
函数中,我希望timerSubtract()
函数在totalTime() > 0
时重复,但如果我使用while循环,页面就会崩溃。为什么这样做?我不认为这是一个无限循环。我该怎么做才能想要?
感谢无论谁回答! : - )
答案 0 :(得分:6)
问题在于timerSubtract
使用setTimeout
进行了工作。
每次使用setTimeout
时,您都可以想象它会暂时搁置该功能。然后,一旦程序没有做任何事情(如果已经过了足够的时间),那么它将运行下一个被搁置的功能。通过运行while
循环,您永远不会让运行时有机会使用setTimeout
运行您的函数。
在使用setTimeout
时解决此问题的一种方法是执行以下操作:
function timerRun() {
if (minutes > 0 && seconds == 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
timerPrint();
// Queue up timerRun to run again in 1 second
setTimeout(timerRun, 1000);
}
timerRun();
答案 1 :(得分:2)
为什么不使用setInterval:
而不是使用setTimeoutsetInterval(function () {
if(minutes > 0 && seconds == 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
timerPrint();
}, 1000);
选中此项以了解如何停止计时器:how to stop "setInterval"
答案 2 :(得分:0)
timerSubtract
函数不会更改变量minutes
或seconds
。它只会启动一个超时,以便稍后更改变量。
如果在循环中运行函数等待变量更改,那么变量将永远不会有任何变化。 JavaScript是单线程的,因此您必须退出该函数并将控件返回到浏览器以执行超时。循环运行时,不会处理超时事件。
如果JavaScript是多线程的,那么你的循环将启动数百万次超时,直到一秒钟过去并且超时将开始执行。由于您没有每秒启动超时但速度尽可能快,因此当时计时器会立即倒数至数百万。
在setInterval
中使用单个timerSubtract
,而不是启动大量超时,而只调用该函数一次。间隔将每秒倒计时一次,因为我怀疑你的计时器是如何工作的:
function timerSubtract(inputMinutes, inputSeconds) {
setInterval(function () {
if(minutes > 0 && seconds == 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
timerPrint();
}, 1000);
}
function timerRun() {
timerSubtract();
}
答案 3 :(得分:0)
正如Jonathan发布的那样,您可以使用setInterval。我会在他的答案中添加clearInterval()来停止在0(这是你想要的吗?) 像这样:
function timerSubtract(inputMinutes, inputSeconds) {
var countdown = setInterval(function () {
if(minutes > 0 && seconds == 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
if( totalTime() <= 0){
clearInterval(countdown);
// timer is done, do something interesting..
}
timerPrint();
}, 1000);
}
此外,很长一段时间计时器可能不准确。如果您想要更好的精度,请在启动计时器时读取实际当前系统时间,然后在每个时间间隔再次读取实际时间并减去两个值(当前 - 开始)以获得实际经过的时间。然后从初始总计中减去经过的时间,以获得当前剩余的时间。