This article shows you how to create an Accurate stopwatch in Javascript. In another article, we have already created a simple stopwatch(See here). But there is a problem you might observe the result of Stopwatch is not accurate.
The reason for the problem is we depend on setTimeout() method alone. The setTimeout() calls the callback method at the specified milliseconds only but the code execution time of the callback depends on the scheduler that may cause a delay in execution time.
To overcome the above problem, in this article we are going to use the Date.now() along with setTimeout() to make it more accurate. We will also see how to create it using the setInterval() method. There are little differences between setTimeout() and setInterval().
Let’s start creating a more accurate stopwatch…
Table of Contents
How to create an accurate timer in javascript?
We will see here two app
Accurate stopwatch using setTimeout in javascript
You just need to follow the below steps:
- Define HTML
- Define CSS
- Javascript for timer
1. Define HTML
<!DOCTYPE html>
<html>
<head>
<title>JavaScript StopWatch</title>
</head>
<body>
<div id="stopwatch-container">
<p id="stopwatch">00:00:00:00</p>
<div id="buttons-container">
<button onclick="main()" id="main-btn" class="btn">Start</button>
<button onclick="reset()" id="reset-btn" class="btn">Reset</button>
</div>
</div>
</body>
</html>
Explanation:
- Defined an HTML
<p>
tag withid="stopwatch"
to display the time in 00:00:00:00 format. - Defined two buttons with
id="main-btn"
andid="reset-btn"
to operate stopwatch application. - Creating a div area as a container with
id="stopwatch-container"
to contain stopwatch.
2. Define CSS
#stopwatch-container {
display: flex;
justify-content: center;
flex-direction: column;
margin: 100px auto 0;
width: fit-content;
padding: 10px 20px;
box-shadow: 1px 0px 4px 2px #9c9a9a;
border-radius: 5px;
}
#stopwatch {
margin: 0 auto;
text-align: center;
font-size: 60px;
}
#buttons-container {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
#buttons-container button {
outline: none;
cursor: pointer;
color: #fff;
background-color:#000;
border: none;
border-radius: 5px;
font-size: 20px;
margin: 0 10px;
padding: 3px 8px;
}
#buttons-container button:active {
opacity: 0.7;
}
3. Javascript for Timer
Now let’s define the javascript for the timer (Stopwatch) below:
//globle variables
var stopwatch = document.getElementById('stopwatch');
var mainButton = document.getElementById('main-btn');
var startTime=0;
var elapsedTime=0;
var timeoutId=null;
//method to operate start and stop function
function main(){
if (mainButton.innerHTML === 'Start') {
startTime = Date.now();
startStopwatch();
mainButton.innerHTML = 'Stop';
} else {
elapsedTime += Date.now() - startTime;
clearTimeout(timeoutId);
mainButton.innerHTML = 'Start';
}
}
//method to reset the stopwatch
function reset() {
elapsedTime = 0;
startTime = Date.now();
clearTimeout(timeoutId);
mainButton.innerHTML = 'Start';
displayTime(0, 0, 0, 0);
}
//method to start the stopwatch
function startStopwatch() {
//run setTimeout() and save id
timeoutId = setTimeout(function(){
//calculate elapsed time
const time = Date.now() - startTime + elapsedTime;
//calculate different time measurements based on elapsed time
const milliseconds = parseInt((time%1000)/10)
const seconds = parseInt((time/1000)%60)
const minutes = parseInt((time/(1000*60))%60)
const hour = parseInt((time/(1000*60*60))%24);
//display time
displayTime(hour, minutes, seconds, milliseconds);
//calling same method again recursivelyÂ
startStopwatch();
}, 100);
}
//method to display time in '00:00:00:00' format
function displayTime(hour, minutes, seconds, milliseconds) {
hour = hour < 10 ? '0'+hour : hour ;
minutes = minutes < 10 ? '0'+minutes : minutes ;
seconds = seconds < 10 ? '0'+seconds : seconds ;
milliseconds = milliseconds < 10 ? '0'+milliseconds : milliseconds ;
stopwatch.innerHTML = hour+':'+minutes+':'+seconds+':'+milliseconds;
}
Explanation:
- We have Defined some global variables here as
stopwatch
,mainButton
,startTime
,elapsedTime
, andtimeoutId
. stopwatch
hold the reference of<p>
tag element to display the time.mainButton
is used to hold the reference of main button to update the button text(start and stop).startTime
andelapsedTime
are used to hold the start time and elapsed time respectively.timeoutId
hold the id returnd bysetTimeout()
and it is used to clear or stop the timer.- We have defined four method as
main()
,startStopwatch()
,displayTime()
, andreset()
. - The
main()
method is used to operate the start and stop functionality of the stopwatch. - The
startStopwatch()
method is used to calculate the time in hour, minute, seceond, and milliseconds. We call this method recursively to continue calculating the same. - Here we used
setTimeout()
method which executes only once, that is why we calledstartStopwatch()
recursively to repeat the process. - The
displayTime()
method is used to display the time in 00:00:00:00 format. - The
reset()
method is used to reset the stopwatch. Here weclearTimeout()
method to clear the timer by passing the timeoutId.
Stopwatch timer example in Javascript (complete source code)
Below is the complete example (putting all HTML, CSS, and Javascript code in a single file) of an accurate stopwatch application using the setTimeout()
method and Date.now()
method.
<!DOCTYPE html>
<html>
<head>
<title>JavaScript StopWatch</title>
<style>
#stopwatch-container {
display: flex;
justify-content: center;
flex-direction: column;
margin: 100px auto 0;
width: fit-content;
padding: 10px 20px;
box-shadow: 1px 0px 4px 2px #9c9a9a;
border-radius: 5px;
}
#stopwatch {
margin: 0 auto;
text-align: center;
font-size: 60px;
}
#buttons-container {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
#buttons-container button {
outline: none;
cursor: pointer;
color: #fff;
background-color:#000;
border: none;
border-radius: 5px;
font-size: 20px;
margin: 0 10px;
padding: 3px 8px;
}
#buttons-container button:active {
opacity: 0.7;
}
</style>
</head>
<body>
<div id="stopwatch-container">
<p id="stopwatch">00:00:00:00</p>
<div id="buttons-container">
<button onclick="main()" id="main-btn" class="btn">Start</button>
<button onclick="reset()" id="reset-btn" class="btn">Reset</button>
</div>
</div>
<script>
//globle variables
var stopwatch = document.getElementById('stopwatch');
var mainButton = document.getElementById('main-btn');
var startTime=0;
var elapsedTime=0;
var timeoutId=null;
//method to operate start and stop function
function main(){
if (mainButton.innerHTML.trim() === 'Start') {
startTime = Date.now();
startStopwatch();
mainButton.innerHTML = 'Stop';
} else {
elapsedTime += Date.now() - startTime;
clearTimeout(timeoutId);
mainButton.innerHTML = 'Start';
}
}
//method to reset the stopwatch
function reset() {
elapsedTime = 0;
startTime = Date.now();
clearTimeout(timeoutId);
mainButton.innerHTML = 'Start';
displayTime(0, 0, 0, 0);
}
//method to start the stopwatch
function startStopwatch() {
//run setTimeout() and save id
timeoutId = setTimeout(function(){
//calculate elapsed time
const time = Date.now() - startTime + elapsedTime;
//calculate different time measurements based on elapsed time
const milliseconds = parseInt((time%1000)/10)
const seconds = parseInt((time/1000)%60)
const minutes = parseInt((time/(1000*60))%60)
const hour = parseInt((time/(1000*60*60))%24);
//display time
displayTime(hour, minutes, seconds, milliseconds);
//calling same method again recursivaly
startStopwatch();
}, 100);
}
//method to display time in '00:00:00:00' format
function displayTime(hour, minutes, seconds, milliseconds) {
hour = hour < 10 ? '0'+hour : hour ;
minutes = minutes < 10 ? '0'+minutes : minutes ;
seconds = seconds < 10 ? '0'+seconds : seconds ;
milliseconds = milliseconds < 10 ? '0'+milliseconds : milliseconds ;
stopwatch.innerHTML = hour+':'+minutes+':'+seconds+':'+milliseconds;
}
</script>
</body>
</html>
Javascript stopwatch Timer Live Demo
00:00:00:00
Accurate stopwatch using setInterval in javascript
The setInterval()
method in JavaScript is used to repeat a specified function at every given time interval. The setInterval()
method continues calling the function until clearInterval()
is called, or the window is closed.
Here we use the same HTML and CSS code from the above example, only we need to modify the javascript logic.
//globle variables
var stopwatch = document.getElementById('stopwatch');
var mainButton = document.getElementById('main-btn');
var startTime=0;
var elapsedTime=0;
var intervalId=null;
//method to operate start and stop function
function main(){
if (mainButton.innerHTML === 'Start') {
startTime = Date.now();
startStopwatch();
mainButton.innerHTML = 'Stop';
} else {
elapsedTime += Date.now() - startTime;
clearInterval(intervalId);
mainButton.innerHTML = 'Start';
}
}
//method to reset the stopwatch
function reset() {
elapsedTime = 0;
startTime = Date.now();
clearInterval(intervalId);
mainButton.innerHTML = 'Start';
displayTime(0, 0, 0, 0);
}
//method to start the stopwatch
function startStopwatch() {
//run setInterval() and save id
intervalId = setInterval(function(){
//calculate elapsed time
const time = Date.now() - startTime + elapsedTime;
//calculate different time measurements based on elapsed time
const milliseconds = parseInt((time%1000)/10)
const seconds = parseInt((time/1000)%60)
const minutes = parseInt((time/(1000*60))%60)
const hour = parseInt((time/(1000*60*60))%24);
//display time
displayTime(hour, minutes, seconds, milliseconds);
}, 100);
}
//method to display time in '00:00:00:00' format
function displayTime(hour, minutes, seconds, milliseconds) {
hour = hour < 10 ? '0'+hour : hour ;
minutes = minutes < 10 ? '0'+minutes : minutes ;
seconds = seconds < 10 ? '0'+seconds : seconds ;
milliseconds = milliseconds < 10 ? '0'+milliseconds : milliseconds ;
stopwatch.innerHTML = hour+':'+minutes+':'+seconds+':'+milliseconds;
}
NOTE: Here you may notice we are not calling the startStopwatch() method recursively because we used setInterval() method and it calls the callback method every time after the specified interval by default.
Conclusion
Here you have seen creating an accurate stopwatch timer application using the setTimeout() as well as the setInterval(). You have also seen we use Date.now() method to make it more accurate.
Hope you like it. If you have any queries related to this article, write them down in the comment section below.