4

I have created this stopwatch and it runs pretty well. The only problem that I am having is that whenever I click my "stop" button, the time stops on the screen but it is still running in the background.

Is there any way to stop this from happening? I want the timer to stop on its current time, then when I click "start", it resumes from the time it was stopped on.

Im thinking maybe create a "new Date()" variable before the update function and another "new Date()" variable inside of the update function and somehow subtract those to get the current date. But I cannot figure that out either.

start = document.getElementById('Start');
        stop = document.getElementById('Stop');
        let watchRunning = false;

        Start.addEventListener('click', startHandler);
        Stop.addEventListener('click', stopHandler);

        function startHandler() {
            if (!watchRunning) {
                watchRunning = setInterval(update, 70);
            }
        }
        function stopHandler() {
            clearInterval(watchRunning);
            watchRunning = null;
        }

        update();
        var seconds;
        var milliseconds;
        var d;

        function update() {
            d = new Date();
            seconds = d.getSeconds();
            milliseconds = Math.floor((d.getMilliseconds() / 10));

            if (milliseconds < 10 && seconds < 10) {
                document.getElementById("Time").innerHTML =
                    "0" + seconds + ".0" + milliseconds;

            } else if (milliseconds < 10 && seconds >= 10) {
                document.getElementById("Time").innerHTML =
                    seconds + ".0" + milliseconds;

            } else if (milliseconds >= 0 && seconds < 10) {
                document.getElementById("Time").innerHTML =
                    "0" + seconds + "." + milliseconds;

            } else if (milliseconds >= 0 && seconds >= 10) {
                document.getElementById("Time").innerHTML =
                    seconds + "." + milliseconds;
            }
        }
#Time {
            background-color: yellow;
            max-width: 2.3%;
        }
<h1>Stop Watch</h1>
    <button id="Start">Start</button>
    <button id="Stop">Stop</button>
    <h3>Elapsed Time:</h3>
    <p id="Time"></p>

Try running the snippet and you will see what I mean. The time doesn't stop "running" after I click stop, and when I click start it resumes as if it was never stopped.

John Doee
  • 207
  • 4
  • 15

2 Answers2

1
clearTimeout( return ID of setTimeout() );

clearTime variable is returned as a value by the setTimeout( ) timing method, which can be pass to the clearTimeout( ID ) as an ID to reference it - clearTimeout( clearTime );

How It Works

Whenever the clearTimeout( ) timing method is called on a setTimeout( ) timing method that is active, the clearTimeout( ) timing method will stop the execution of the setTimeout( ) timing method but without destroying its execution entirely.

The setTimeout( ) timing method is left idle during the period that the clearTimeout( ) timing method is called, and when you re-execute the setTimeout( ) timing method, it will start from the point its execution was stopped, not starting all over from the beginning.

You're good to go!

Akshay Mulgavkar
  • 1,727
  • 9
  • 22
0

You should use a setInterval to run your code to update the stopwatch instead of relying on a Date; you can not stop the Date from changing, so even though you stopped updating your stopwatch, the seconds are still ticking by which makes it seem like your stopwatch never stopped.

#Time {
  background-color: yellow;
  max-width: 2.3%;
}
<h1>Stop Watch</h1>
<button id="Start">Start</button>
<button id="Stop">Stop</button>
<h3>Elapsed Time:</h3>
<p id="Time">00:00</p>
<script>
var start = document.getElementById('Start'), stop = document.getElementById('Stop'), time = document.getElementById('Time');
function StopWatch(props){
   this.seconds = props.seconds||0;
   this.milliseconds = props.milliseconds||0;
   this.updateCallback = props.updateCallback;
   this._running = false;
}
StopWatch.prototype = {
  start: function(){
  var _this = this;
   if(!_this._running){
   _this._running = true;
    _this._intervalID = window.setInterval(function(){
      if(++_this.milliseconds==100){
        _this.seconds++;
        _this.milliseconds = 0;
      }
      if(_this.updateCallback){
        _this.updateCallback(_this.milliseconds, _this.seconds);
      }
    }, 10);
    }
  },
  stop: function(){
    window.clearInterval(this._intervalID);
    this._running = false;
  },
  getTimeString: function(){
     var ms = this.milliseconds, s = this.seconds;
     if(ms<10){
      ms = "0"+ms;
     }
     if(s<10){
      s = "0"+s;
     }
     return s + ":" + ms;
  }
}
var sw = new StopWatch({updateCallback: function(){
  time.textContent = sw.getTimeString();
}});
start.addEventListener('click', function(){
sw.start();
});
stop.addEventListener('click', function(){
sw.stop();
});
</script>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80