0

I'm new to JS and I'm stuck trying to figure out what's causing my countdown timer not to countdown. The user enters the time in 00:00:00 format minutes, seconds, and milliseconds. Afterwards, I convert that format to seconds to begin the process of counting down. I think the calculations is fine, but something is not causing it not to behave as it should be. I've tested and see that the code runs in terms of entering the time and showing up in the output. I see the countdown decrementing, for both seconds and milliseconds at the same time but it should go from 10:00:00 to 09:59:99.. 09:59:98... Basically seconds won't change until milliseconds reaches zero. so 09:59:00 will be 09:58:99... Please any help is greatly appreciated. I've been going at this and been stuck.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script type="text/javascript">

   var running = 0; //Glob variable for starting/pausing timer

   function startPause(){ 
      var time = document.getElementById("timeEntered").value; //Not sure if needed but I just have the time entered be converted to seconds.
      var a = time.split(":");
      var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
      if(running == 0){ //If off, turn it on. 
         running = 1;
         countDown();
         document.getElementById("startPause").innerHTML = "Start/Stop";
      }else{
        running = 0;
        document.getElementById("startPause").innerHTML = "Resume";
      }
   }

   function countDown() {
      var time = document.getElementById("timeEntered").value; //Take user input and convert 00:00:00 format to seconds. 
      var a = time.split(":");
      if(!timeToSeconds)
      var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);
      if(running == 1){ //When user clicks start it will calculate the minutes, seconds, and milliseconds. 
         var minutes = Math.floor(timeToSeconds / 60);
         var seconds = timeToSeconds % 60;
         var milli = timeToSeconds % 100;
         if(minutes <= 9) { //Add leading zeroes to display countdown in 00:00:00 format.
             minutes = "0" + minutes;
         }
         if(seconds <= 9) {
             seconds = "0" + seconds;
         }
         if(milli <= 9) {
             milli = "0" + milli;
         }
         timeToSeconds--; //Decrement the time entered.
         console.log(timeToSeconds); 
         document.getElementById("output").innerHTML = minutes + ":" + seconds + ":" + milli //Display the time 00:00:00 format. 
         if(timeToSeconds !== -1){
             setTimeout('countDown()',100);
         }
         if(timeToSeconds == 0){ //When time is 00:00:00 the message will show. 
             document.getElementById("output").innerHTML = "The time is over."
         }
     }
  }

</script>
</head>
<body>
   <h1>Countdown Timer</h1>
   <div id="mainCont">
   <input type="text" id="timeEntered">
   <p>
     <button id="startPause" onclick="startPause()">Start/Stop</button>
   </p>
     <div id="output">00:00:00</div>
  </div>
</body>
</html>
user5544269
  • 21
  • 1
  • 3
  • 2
    This is too vague to be answered, you should describe what happens, what you expect to happen, what you tried. – pvg Dec 13 '15 at 02:04
  • Please learn how to use the JavaScript console and debug your code, doing a `console.log(timeToSeconds)` shows your problem. The value never changes. Because you keep getting it from your `input` which is static. The calls the function are being made, but the values are never changing. – Spencer Wieczorek Dec 13 '15 at 02:09
  • [Here is the code with the applied fix](http://jsfiddle.net/973mgv4L/). Is that what you are expecting or is there still something wrong with it (*I'm assuming you are not expecting the middle value to increment as it is*)? If so please describe what the problem is and what you are expecting. – Spencer Wieczorek Dec 13 '15 at 02:13
  • I appreciate the help Spencer... However the countdown should function like a stopwatch but in reverse. Where the milliseconds decrements and before the seconds can change, milliseconds have to reach from 100-0 first like so. 10:00:00... 09:59:99... 09:59:98.. Of course this would be simulated fast until 09:59:00.. 09:58:99. Right now it's having seconds and milliseconds decrement at the same time. – user5544269 Dec 13 '15 at 02:18
  • @user5544269 That's because neither `mili` or `seconds` where multiplied by any number, so they will be the same value apart from their modulus operator. I've added my answer below. – Spencer Wieczorek Dec 13 '15 at 03:12

1 Answers1

0

There are a handful of problem here, so I will go over each one and show you the solution. The first problem is that the value of timeToSeconds is the same on each iteration. The reason for this is because you are getting the value from the same unchanging source, decrementing does nothing as the value is lost on the next function call. To fix this have your function take a parameter in which you pass the remaining seconds off after you modified it:

function countDown(timeToSeconds) {
    ...
    timeToSeconds-=0.1; //Decrement the time entered.

    if(timeToSeconds <= 0){ //When time is 00:00:00 the message will show. 
         document.getElementById("output").innerHTML = "The time is over."
         return;
     }
     else if(timeToSeconds !== -1){
         setTimeout(function(){countDown(timeToSeconds)},100);
     }

Notice I only subtracted 0.1 because our setTimeout is called after 100 milliseconds (0.1 seconds). I've also switched around the checks, as before hand you would call the timer even if timeToSeconds was 0.

The next thing was you conversion to seconds was off, in your code here:

var timeToSeconds = (+a[0]) * 60 + (+a[1]) * 60 + (+a[2]);

Both minutes and seconds are calculated in the same way, a[1] is the seconds value and should not be multiplied. And a[2] is actually 10*milliseconds (1 seconds = 1000 milliseconds). That value should be divide by 100:

  if(!timeToSeconds)
    var timeToSeconds = (+a[0]) * 60 + (+a[1]) + (Math.floor(+a[2]/100));

The if-statement is a basic check if the value is true (being any number). In our case it can work as a "Does this value exist" check, since we are only dealing with positive numbers. And the following conversions should be:

 var minutes = Math.floor(timeToSeconds / 60) % 60;
 var seconds = Math.floor(timeToSeconds) % 60;
 var milli = Math.floor(timeToSeconds*100) % 100;

For the most part, your values for minutes and seconds where correct. Although the reason why milli and seconds appeared the same was because you never converted milli to it's correct value, as such they will have the same value apart from the % applied.

Here is the final result

One last thing I would like to point out is that this timer will not be exact. As it takes some time between the computation and the setTimeout call. For a more accuracy value you will want to use Date.now() and find the different between the start time and the current timer. This question uses such a method to do so, which can be applied to the countdown timer in the same fashion.

Community
  • 1
  • 1
Spencer Wieczorek
  • 21,229
  • 7
  • 44
  • 54