我在javascript中编写一个简单的倒数计时器,带有播放和暂停按钮。当我启动它时它工作正常,但如果我暂停/播放几次定时器值随机变化,我无法弄清楚原因。
这是我的代码:
var minutesleft = 60;
var secondsleft = 0;
var millisecondsleft = 0;
var bool = true;
var paused = false;
var end;
var now;
function pause(){
paused = true;
}
function stop(){
end = now;
bool = true;
}
function cd(){
if (bool) {
end = new Date();
end.setMinutes(end.getMinutes()+minutesleft);
end.setSeconds(end.getSeconds()+secondsleft);
end.setMilliseconds(end.getMilliseconds()+millisecondsleft);
bool = false;
}
now = new Date();
diff = end - now;
diff = new Date(diff);
var msec = diff.getMilliseconds();
var sec = diff.getSeconds();
var min = diff.getMinutes();
if (min < 10){
min = "0" + min;
}
if (sec < 10){
sec = "0" + sec;
}
if(msec < 10){
msec = "00" +msec;
}
else if(msec < 100){
msec = "0" +msec;
}
if(now >= end){
clearTimeout(timerID);
document.getElementById("cdtime").innerHTML = 'POLICE IS HERE';
}
else{
document.getElementById("cdtime").innerHTML = min + ":" + sec + ":" + msec;
}
if (paused == false){
timerID = setTimeout("cd()", 10);
}
else {
bool = true;
minutesleft = min;
secondsleft = sec;
millisecondsleft = msec;
}
paused = false;
}
这是一个小提琴:https://jsfiddle.net/cw3s5124/
提前致谢
答案 0 :(得分:2)
跳转数字的主要问题是由于字符串连接,然后在日期函数中使用该字符串。部分代码如下:
if (min < 10){
min = "0" + min;
}
证明为何发生这种情况的一个例子
var end1 = new Date();
var minutesleft1 = 9;
console.log("Minutes to assign to current time");
console.log(end1.getMinutes() + minutesleft1); // Logs expected amount of minutes to calculate
end1.setMinutes(end1.getMinutes() + minutesleft1);
var end2 = new Date();
var minutesleft2 = "09";
console.log("Wrong Minutes to assign to current time");
console.log(end2.getMinutes() + minutesleft2); // Logs big number
end2.setMinutes(end2.getMinutes() + minutesleft2);
console.log(end1); // Logs expected result
console.log(end2); // Logs a time a day or so in the future
■
说明:如果您在分钟var中将启动计时器设置为9,则需要立即填充0以进行显示。由于您现在将minutesleft
变量设置为"09"
,因此当您致电9 + "09"
时,您实际上正在end.setMinutes(end.getMinutes()+minutesleft);
将字符串"0"
连接到数字后,您实际上是在尝试使用字符串进行数字运算,这会导致意外结果。这个并非在一开始就发生了,因为你的if语句还没有运行,因此min
,sec
和msec
变量仍然是数字。 您只应在显示数字时填充数字,而不是计算本身。
我用从this post借来的填充函数替换了字符串连接。
我还添加了一个播放功能来重置你的暂停参数。这使代码更易读,更易于理解。此外,将其更改为在开始时暂停,因为计时器尚未运行。
var minutesleft = 10;
var secondsleft = 05; // This would normally just be returned as 5, that's why we need the pad function for display
var millisecondsleft = 0;
var firstCall = true;
var paused = true;
var end;
var now;
function pause() {
paused = true;
}
function play() {
if (paused === false) // Shorcut out because we are already running
return;
paused = false;
cd();
}
function stop() {
end = now;
paused = true;
cd();
}
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById("cdtime").innerHTML = pad(minutesleft, 2) + ":" + pad(secondsleft, 2) + ":" + pad(millisecondsleft, 2);
});
function cd() {
if (firstCall) {
end = new Date();
end.setMinutes(end.getMinutes() + minutesleft);
end.setSeconds(end.getSeconds() + secondsleft);
end.setMilliseconds(end.getMilliseconds() + millisecondsleft);
firstCall = false;
}
now = new Date();
diff = end - now;
diff = new Date(diff);
var msec = diff.getMilliseconds();
var sec = diff.getSeconds();
var min = diff.getMinutes();
if (now >= end) {
clearTimeout(timerID);
document.getElementById("cdtime").innerHTML = 'POLICE IS HERE';
} else {
document.getElementById("cdtime").innerHTML = pad(min, 2) + ":" + pad(sec, 2) + ":" + pad(msec, 2);
}
if (paused === false) {
timerID = setTimeout("cd()", 10);
} else {
bool = true;
minutesleft = min;
secondsleft = sec;
millisecondsleft = msec;
}
}
function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
&#13;
<body>
<div id='timer'>
<button class='playerButtons' id='playT' type='submit' onclick='play()'>Play</button>
<button class='playerButtons' id='pauseT' type=' submit' onclick='pause()'>Pause</button>
<button class='playerButtons' id='stopT' type='submit' onclick='stop()'>Stop</button>
<div id='cdtime'></div>
</div>
</body>
&#13;
答案 1 :(得分:1)
您在错误的位置重置暂停和布尔。如果你看看JsFiddle,你可以看到需要删除的内容
var minutesleft = 60;
var secondsleft = 0;
var millisecondsleft = 0;
var bool = true;
var paused = true;
var end;
var now;
function pause(){
paused = true;
//bool = false; //shouldn't be here (move to stop function)
}
function play(){
if ( paused === true){
paused = false;
bool = true;
cd();
}
}
function stop(){
end = now;
bool = false; //add here
}
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById("cdtime").innerHTML = minutesleft + ":" + secondsleft + "0:" + millisecondsleft + "0";
});
function cd(){
if (bool) {
end = new Date();
end.setMinutes(end.getMinutes()+minutesleft);
end.setSeconds(end.getSeconds()+secondsleft);
end.setMilliseconds(end.getMilliseconds()+millisecondsleft);
bool = false;
}
now = new Date();
diff = end - now;
diff = new Date(diff);
var msec = diff.getMilliseconds();
var sec = diff.getSeconds();
var min = diff.getMinutes();
if (min < 10){
min = "0" + min;
}
if (sec < 10){
sec = "0" + sec;
}
if(msec < 10){
msec = "00" +msec;
}
else if(msec < 100){
msec = "0" +msec;
}
if(now >= end){
clearTimeout(timerID);
document.getElementById("cdtime").innerHTML = 'POLICE IS HERE';
}
else{
document.getElementById("cdtime").innerHTML = min + ":" + sec + ":" + msec;
}
if (paused === false){
timerID = setTimeout("cd()", 10);
}
else {
bool = true;
minutesleft = min;
secondsleft = sec;
millisecondsleft = msec;
}
//paused = false; //shouldn't be here
}
<body>
<div id='timer'>
<button class='playerButtons' id='playT' type='submit' onclick='play()'>Play</button>
<button class='playerButtons' id='pauseT' type=' submit'onclick='pause()'>Pause</button>
<button class='playerButtons' id='stopT' type='submit' onclick='stop()'>Stop</button>
<div id='cdtime'></div>
</div>
</body>