暂停时倒数计时器javascript错误

时间:2015-12-09 16:06:31

标签: javascript timer

我在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/

提前致谢

2 个答案:

答案 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语句还没有运行,因此minsecmsec变量仍然是数字。 您只应在显示数字时填充数字,而不是计算本身。

我用从this post借来的填充函数替换了字符串连接。

我还添加了一个播放功能来重置你的暂停参数。这使代码更易读,更易于理解。此外,将其更改为在开始时暂停,因为计时器尚未运行。

&#13;
&#13;
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;
&#13;
&#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>

https://jsfiddle.net/cw3s5124/27/