Syntax Error
Syntax Error

Reputation: 1

Stopwatch Timer is slower than normal time

I want to make a stopwatch in JavaScript that could count milliseconds, seconds, minutes, and hours. The problem is that it seems to not go at the proper speed, meaning that when I compare it to other timers, it gradually becomes slower than them (i.e the speed at which the timer is counting slows down over time). So suddenly, there are 5-second differences, then it becomes 7-second differences, and so on. Any help would be appreciated. My code for Stopwatch.

var hr = 0;
var min = 0;
var sec = 0;
var count = 0;

var Startbutton = document.getElementById("Start");


var timer = false;

function start() {
  Startbutton.disabled = true; //this wil help to avoid multiple clicking on function
  timer = true;
  stopwatch();
}

function stop() {
  timer = false;
  Startbutton.disabled = false;

}

function reset() {
  timer = false;
  Startbutton.disabled = false;
  min = 0;
  hr = 0;
  sec = 0;
  count = 0;

  document.getElementById("hr").innerHTML = "00";
  document.getElementById("min").innerHTML = "00";
  document.getElementById("sec").innerHTML = "00";
  document.getElementById("count").innerHTML = "00";
}

function stopwatch() {
  if (timer) {
    ++count;
    if (count > 99) {
      ++sec;
      count = 0;
    }
    if (sec > 59) {
      min++;
      sec = 0;
    }
    if (min > 59) {
      hr++;
      min = 0;
      sec = 0;
    }
    if (hr > 23) {
      hr = 0;
      sec = 0;
      min = 0;
    }

    var hrString = hr;
    var minString = min;
    var secString = sec;
    var countString = count;

    if (hr < 10) {
      hrString = "0" + hrString;
    }
    if (min < 10) {
      minString = "0" + minString;
    }
    if (sec < 10) {
      secString = "0" + secString;
    }
    if (count < 10) {
      countString = "0" + countString;
    }
    document.getElementById("hr").innerHTML = hrString;
    document.getElementById("min").innerHTML = minString;
    document.getElementById("sec").innerHTML = secString;
    document.getElementById("count").innerHTML = countString;
    console.log("hello");
    setTimeout(stopwatch, 10);
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Stopwatch</title>
  <link rel="stylesheet" href="style.css" />
</head>

<body>
  <div id="container">
    <div id="time">
      <span class="digit" id="hr">00</span>
      <span class="txt">Hr</span>

      <span class="digit" id="min">00</span>
      <span class="txt">Min</span>

      <span class="digit" id="sec">00</span>
      <span class="txt">Sec</span>


      <span class="digit" id="count">00</span>

    </div>
    <div id="btn-container">
      <button class="btn" id="Start" onclick="start()">Start</button>
      <button class="btn" id="Stop" onclick="stop()">Stop</button>
      <button class="btn" id="Reset" onclick="reset()">Reset</button>
    </div>
  </div>


  <script src="script.js"></script>
</body>

</html>

Upvotes: 0

Views: 722

Answers (2)

Muhammed Yal&#231;ın
Muhammed Yal&#231;ın

Reputation: 39

You should take time from system clock. Otherwise time will be relative in your code :) The code below you can inspect.

var hr = 0;
var min = 0;
var sec = 0;
var count = 0;

var Startbutton = document.getElementById("Start");
var startTime = Date.now();

var timer = false;
function start() {
  Startbutton.disabled = true;  //this wil help to avoid multiple clicking on function
  timer = true;
  startTime = Date.now();
  stopwatch();
}
function stop() {
  timer = false;
  Startbutton.disabled = false;

}
function reset() {
  timer = false;
  Startbutton.disabled = false;
  min = 0;
  hr = 0;
  sec = 0;
  count = 0;

  document.getElementById("hr").innerHTML = "00";
  document.getElementById("min").innerHTML = "00";
  document.getElementById("sec").innerHTML = "00";
  document.getElementById("count").innerHTML = "00";
}


function stopwatch() {
  if (timer) {
    var elapsedTime = Date.now() - startTime;
    var hr = Math.floor(elapsedTime / (60 * 60 * 1000) % 24).toString().padStart(2, '0');
    var min = Math.floor(elapsedTime / (60 * 1000) % 60).toString().padStart(2, '0');
    var sec = Math.floor(elapsedTime / 1000 % 60).toString().padStart(2, '0');
    var msec = Math.floor(elapsedTime % 1000).toString().padStart(2, '0');
    
    document.getElementById("hr").innerHTML = hr;
    document.getElementById("min").innerHTML = min;
    document.getElementById("sec").innerHTML = sec;
    document.getElementById("count").innerHTML = msec;
    setTimeout(stopwatch, 10);
  }
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Stopwatch</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div id="container">
      <div id="time">
        <span class="digit" id="hr">00</span>
        <span class="txt">Hr</span>

        <span class="digit" id="min">00</span>
        <span class="txt">Min</span>

        <span class="digit" id="sec">00</span>
        <span class="txt">Sec</span>

        
        <span class="digit" id="count">00</span>
     
      </div>
      <div id="btn-container">
        <button class="btn" id="Start" onclick="start()">Start</button>
        <button class="btn" id="Stop" onclick="stop()">Stop</button>
        <button class="btn" id="Reset" onclick="reset()">Reset</button>
      </div>
    </div>


    <script src="script.js"></script>
  </body>
</html>

Upvotes: 0

IT goldman
IT goldman

Reputation: 19495

Because you don't take into account the time it takes for it to draw the html. Need to re-design to use system clock. See my example.

var hr = 0;
var min = 0;
var sec = 0;
var count = 0;

var Startbutton = document.getElementById("Start");


var timer = false;
var start_time;

function start() {
  Startbutton.disabled = true; //this wil help to avoid multiple clicking on function
  timer = true;
  start_time = (new Date()).getTime();
  stopwatch();
}

function stop() {
  timer = false;
  start_time = null;
  Startbutton.disabled = false;

}

function reset() {
  timer = false;
  start_time = null;
  Startbutton.disabled = false;
  min = 0;
  hr = 0;
  sec = 0;
  count = 0;

  document.getElementById("hr").innerHTML = "00";
  document.getElementById("min").innerHTML = "00";
  document.getElementById("sec").innerHTML = "00";
  document.getElementById("count").innerHTML = "00";
}

function stopwatch() {
  var now = (new Date()).getTime();
  var diff = now - start_time;
  
  
  if (timer) {
    var str_time = (new Date(diff).toISOString().slice(11, 23)); // 👉️ 15:00:00.000

    var hrString = ""+str_time.substring(0,2);
    var minString = ""+str_time.substring(3,5);
    var secString = ""+str_time.substring(6,8);
    var countString =""+ str_time.substring(9,11);


    document.getElementById("hr").innerHTML = hrString;
    document.getElementById("min").innerHTML = minString;
    document.getElementById("sec").innerHTML = secString;
    document.getElementById("count").innerHTML = countString;
    //console.log("hello");
    requestAnimationFrame(stopwatch)
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Stopwatch</title>
  <link rel="stylesheet" href="style.css" />
</head>

<body>
  <div id="container">
    <div id="time">
      <span class="digit" id="hr">00</span>
      <span class="txt">Hr</span>

      <span class="digit" id="min">00</span>
      <span class="txt">Min</span>

      <span class="digit" id="sec">00</span>
      <span class="txt">Sec</span>


      <span class="digit" id="count">00</span>

    </div>
    <div id="btn-container">
      <button class="btn" id="Start" onclick="start()">Start</button>
      <button class="btn" id="Stop" onclick="stop()">Stop</button>
      <button class="btn" id="Reset" onclick="reset()">Reset</button>
    </div>
  </div>


  <script src="script.js"></script>
</body>

</html>

Upvotes: 1

Related Questions