This article goes over how to build a simple stopwatch web app using HTML and JavaScript.
Seconds
Display seconds with setInterval
and innerText
:
<!-- index.html -->
<h1>0</h1>
<script>
var heading = document.querySelector('h1');
var seconds = 0;
setInterval(function () {
seconds += 1;
heading.innerText = seconds;
}, 1000);
</script>
Minutes and Seconds
Display minutes and seconds in the format of MM:SS
with padStart
:
<!-- index.html -->
<h1>00:00</h1>
<script>
var heading = document.querySelector('h1');
var seconds = 0;
setInterval(function () {
seconds += 1;
heading.innerText = formatTime(seconds);
}, 1000);
function formatTime(seconds) {
var minutes = Math.floor(seconds / 60);
seconds = seconds % 60;
return (
String(minutes).padStart(2, '0') + ':' + String(seconds).padStart(2, '0')
);
}
</script>
Web Worker
If the stopwatch is running but you switch to another tab, you’ll notice the stopwatch is slower than expected.
This is because inactive browser tabs have lower priority execution.
To combat this imprecision, use Web Workers to run setInterval
in a separate background thread.
Move the timing logic to worker.js
but replace set innerText
with postMessage
:
// worker.js
var seconds = 0;
setInterval(function () {
seconds += 1;
postMessage(formatTime(seconds)); // sends message to worker
}, 1000);
function formatTime(seconds) {
var minutes = Math.floor(seconds / 60);
seconds = seconds % 60;
return (
String(minutes).padStart(2, '0') + ':' + String(seconds).padStart(2, '0')
);
}
Update index.html
to create the worker and listen to onmessage
:
<!-- index.html -->
<h1>00:00</h1>
<script>
var heading = document.querySelector('h1');
var worker = new Worker('worker.js');
worker.onmessage = function (event) {
heading.innerText = event.data;
};
</script>
Demo
Check out the GitHub repository or Replit: