Once upon a time, a student is given a stopwatch as an assignment. She confidently says “it’s just an interval timer”, but defeat comes swiftly as she realizes that it is “more than a timer”. Let Master Coffee show you how it’s done – Let’s go.
CODE DOWNLOAD
I have released this under the MIT license, feel free to use it in your own project – Personal or commercial. Some form of credits will be nice though. 🙂
VIDEO TUTORIAL
JAVASCRIPT STOPWATCH DEMO
1) THE HTML
<div id="stopwatch">
<!-- (PART A) CURRENT TIME -->
<div id="swNow">00:00:00.0</div>
<!-- (PART B) START/STOP, RESET, LAP -->
<input type="button" id="swTog" value="Start" disabled>
<input type="button" id="swRst" value="Reset" disabled>
<input type="button" id="swLap" value="Lap" disabled>
<!-- (PART C) LAPS -->
<div id="swLaps"></div>
</div>
As you can see, there are 3 sections to the stopwatch.
<div id="swNow">
To show the current time. We will stick with a “resolution” of a decisecond (1/10 of a second) for this example.- A row of buttons.
<input type="button" id="swTog">
To toggle start/stop time.<input type="button" id="swRst">
Reset the current time.<input type="button" id="swLap">
Add the current time to the lap.
<div id="swLaps">
List of lap times.
2) THE JAVASCRIPT
var sw = {
// (PART A) PROPERTIES
hNow : null, // html current time
hTog : null, // html start/stop
hRst : null, // html reset
hLaps : null, // html laps
secs : 0, // current time in deciseconds (1/10 of a second)
timer : null, // stopwatch timer
// (PART B) INIT
init : () => {
// (B1) GET HTML ELEMENTS
sw.hNow = document.getElementById("swNow");
sw.hTog = document.getElementById("swTog");
sw.hRst = document.getElementById("swRst");
sw.hLap = document.getElementById("swLap");
sw.hLaps = document.getElementById("swLaps");
// (B2) ENABLE BUTTONS
sw.hTog.onclick = sw.tog;
sw.hRst.onclick = sw.reset;
sw.hLap.onclick = sw.lap;
sw.hTog.disabled = false;
sw.hRst.disabled = false;
sw.hLap.disabled = false;
},
// (PART C) START/STOP STOPWATCH
tog : () => {
// (C1) STOP STOPWATCH
if (sw.timer) {
clearInterval(sw.timer);
sw.timer = null;
sw.hTog.value = "Start";
}
// (C2) START STOPWATCH
else {
sw.timer = setInterval(() => {
sw.secs++;
let ds = sw.secs, s = 0, m = 0, h = 0;
// 1 hr = 36000 ds
if (s >= 36000) {
h = Math.floor(ds / 36000);
ds -= h * 36000;
}
// 1 min = 600 ds
if (s >= 600) {
m = Math.floor(ds / 600);
ds -= m * 600;
}
// 1 sec = 10 ds
if (ds >= 10) {
s = Math.floor(ds / 10);
ds -= s * 10;
}
if (h < 10) { h = "0" + h; }
if (m < 10) { m = "0" + m; }
if (s < 10) { s = "0" + s; }
sw.hNow.innerHTML = `${h}:${m}:${s}.${ds}`;
}, 100);
sw.hTog.value = "Stop";
}
},
// (PART D) RESET STOPWATCH
reset : () => {
sw.secs = 0;
sw.hNow.innerHTML = "00:00:00.0";
sw.hLaps.innerHTML = "";
},
// (PART E) ADD LAP
lap : () => {
let row = document.createElement("div");
row.innerHTML = sw.hNow.innerHTML;
row.className = "lap";
row.onclick = row.remove;
sw.hLaps.appendChild(row);
}
};
// (PART F) START
window.addEventListener("load", sw.init);
The Javascript is rather long-winded, but straightforward once you trace through it.
- We define a
var sw = {}
object to contain all the stopwatch mechanics. - (B & F) On window load, call
sw.init()
to initialize. - (A & B) All the initialization does is to get the HTML elements, and attach the respective actions for the buttons –
- Toggle start/stop –
sw.tog()
- Reset time –
sw.reset()
- Add lap –
sw.lap()
- Toggle start/stop –
- (C)
sw.tog()
As above, the secret behind the stopwatch is an interval timer running at every 1/10 second.- (C2) The first click will start the timer. This will simply increment
sw.secs
, calculate the elapsed time and display it nicely in HTML. - (C1) Clicking on the button again will pause the timer.
- (C2) The first click will start the timer. This will simply increment
- (D)
sw.reset()
To reset the time, just setsw.secs = 0
and remove all previous laps. - (E)
sw.lap()
To add a lap, grab the current elapsed time and create a clone of it.
3) THE CSS
/* (PART A) WRAPPER */
#stopwatch {
display: flex; flex-wrap: wrap;
width: 400px; margin: 0 auto; padding: 20px;
color: #fff;
}
/* (PART B) CURRENT TIME */
#swNow {
font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
font-size: 40px; text-align: center;
width: 100%; margin-bottom: 10px;
}
/* (PART C) BUTTONS */
#stopwatch input {
width: 33.3%; padding: 10px;
color: #fff; background: #af3939;
border: 2px solid #2f3440; cursor: pointer;
}
/* (PART D) LAPS */
#swLaps { width: 100%; }
#swLaps .lap {
margin-top: 10px; padding: 8px;
background: #242936;
}
/* (PART X) WHOLE PAGE */
* {
font-family: Arial, Helvetica, sans-serif;
box-sizing: border-box;
}
html, body { background: #2f3440; }
Lastly, some cosmetics for the stopwatch. The CSS is not really important, feel free to style the stopwatch however you wish.
THE END – HOW ABOUT “A MORE ACCURATE STOPWATCH”?
That’s all for this short tutorial and sharing. One last bit before we end, if you want a “smaller time unit”, 1/100 seconds for example:
- (C2) Set the interval timer to run at 10 microseconds (or 1/100 seconds).
- (C2) Adjust the time calculations accordingly –
1 second = 100 centiseconds, 1 minute = 6000 centiseconds, 1 hour = 360000 centiseconds
.