Countdown timers can serve many purposes. They can communicate to a user how long they’ve been doing something or how much time until some event happens, like the launch of your new website. In the sales and marketing context, they can create a sense of urgency to encourage conversion.
In this tutorial, you will create a countdown timer in pure JavaScript.
To complete this tutorial, you will need the following:
Since you’ll be using JavaScript in it’s purest form, without any front-end libraries, there’s not much bootstrapping that has to be done.
Create an index.html
file with the standard boilerplate HTML starter code:
<!DOCTYPE html>
<html>
<body>
</body>
</html>
Add a <div>
within the <body>
. The <div>
should have an id
set to "countdown"
:
<!DOCTYPE html>
<html>
<body>
<div id="countdown"></div>
</body>
</html>
Later on, the JavaScript countdown timer’s output will be placed within this <div>
. Below your <div>
, include <script>
tags. Your <script>
tags will house your JavaScript code:
<!DOCTYPE html>
<html>
<body>
<div id="countdown"></div>
<script>
</script>
</body>
</html>
With your HTML in place, you’re ready to move on to coding your countdown timer with JavaScript. In the next step, you’ll calculate the time remaining for the countdown.
Before calculating the time remaining, create a function called countdownTimer
:
<!DOCTYPE html>
<html>
<body>
<div id="countdown"></div>
<script>
function countdownTimer() {
}
</script>
</body>
</html>
To calculate the time remaining, you need to find the difference between the current time and the time that your countdown timer will expire. Within the countdownTimer
function, create a constant variable called difference
. In the code snippet below, difference
will be set equal to the difference between New Year’s Day in 2021 and the current date:
function countdownTimer() {
const difference = +new Date("2021-01-01") - +new Date();
}
new Date
creates a date object. The +
before the new Date
is shorthand to tell JavaScript to cast the object as an integer, which gives you the object’s Unix timestamp represented as microseconds since the epoch.
Below the difference
constant variable, create a variable called remaining
. remaining
will be set equal to a "Time's up!"
message:
function countdownTimer() {
const difference = +new Date("2020-01-01") - +new Date();
let remaining = "Time's up!";
}
When your time runs out and the countdown timer ends, the remaining
message will be displayed.
The time remaining on your countdown timer is all set. The remaining time (the difference
) is calculated in milliseconds. Now you need to format the time remaining into days, hours, minutes, and seconds.
With the total number of milliseconds until the countdown time expires calculated, you need to convert the number of milliseconds to something more human readable. Before you do this, you will need to create an if
statement:
function countdownTimer() {
const difference = +new Date("2020-01-01") - +new Date();
let remaining = "Time's up!";
if (difference > 0) {
}
}
If difference
is greater than 0
(if it’s not New Year’s day), the code to follow will be executed.
Now you can convert milliseconds to days, hours, minutes, and seconds. To do this, you will need to do some division, multiplication and use the modulus %
operator.
Create an object with the constant variable name parts
. The keys in the object should be days
, hours
, minutes
, and seconds
, and the corresponding values should match the equation you’ll need to convert milliseconds to the appropriate unit of time. The code snippet below will show these equations:
if (difference > 0) {
const parts = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
}
The Math.floor
function is used to round the numbers down. With this in place, you are able to drop the remainder to get the whole number value for each unit of time.
The object full of the days, hours, minutes, and seconds remaining will need to be formatted into a string. To do that, reassign remaining
and set it equal to an array of the keys in parts
. Use the Object.keys
method to do this:
if (difference > 0) {
const parts = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
remaining = Object.keys(parts)
}
remaining
is now set equal to an array of the keys in parts
. Since remaining
is now an array, you can use the .map()
method. The .map()
method will iterate over each item in remaining
and allow you to perform a function on each item.
if (difference > 0) {
const parts = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
remaining = Object.keys(parts).map(part => {
})
}
You want to convert each item to a string. Each unit of time should follow this format: “X days.” part
matches the unit of time. To grab the actual number, you will need to use bracket notation with the parts
object. Create an if
statement that checks if there is no number for the corresponding unit of time. If there is no number, add a return statement:
remaining = Object.keys(parts).map(part => {
if (!parts[part]) return;
})
If there is no corresponding number, the .map()
method will move on to the next unit of time and check again.
If there is a number, return the number along with the unit of time. Remember, it should follow the “X days” format:
remaining = Object.keys(parts).map(part => {
if (!parts[part]) return;
return `${parts[part]} ${part}`;
})
${parts[part]}
will return the number while ${part}
will return the unit of time. Now, remaining
is an array of days, hours, minutes, and seconds. This array needs to be a string. Each item in remaining
should be seperated by a space. Use the .join(" ")
method to accomplish this:
remaining = Object.keys(parts).map(part => {
return `${parts[part]} ${part}`;
}).join(" ");
Right now, your countdownTimer()
function will look like this:
function countdownTimer() {
const difference = +new Date("2020-01-01") - +new Date();
let remaining = "Time's up!";
if (difference > 0) {
const parts = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
remaining = Object.keys(parts).map(part => {
return `${parts[part]} ${part}`;
}).join(" ");
}
}
The time remaining is now formatted into a string and units of time that are understandable. However, the time remaining will not display on your page yet. To accomplish this, you’ll need to use DOM manipulation.
With the time parts assembled into a string, you can update your <div>
to contain the value. To do this, you’ll need to use DOM Manipulation.
Within your countdownTimer()
function and below your if
statment, use the getElementById
DOM selector to reference the <div>
with an id
of "countdown"
:
function countdownTimer() {
const difference = +new Date("2020-01-01") - +new Date();
let remaining = "Time's up!";
if (difference > 0) {
const parts = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
remaining = Object.keys(parts).map(part => {
return `${parts[part]} ${part}`;
}).join(" ");
}
document.getElementById("countdown")
}
To alter the contents of this <div>
, you will also need to use the .innerHTML
property attached to document.getElementById("countdown")
. Set this DOM selector equal to remaining
:
document.getElementById("countdown").innerHTML = remaining;
Now, the countdownTimer()
function is complete. Call the function for it to run:
function countdownTimer() {
const difference = +new Date("2020-01-01") - +new Date();
let remaining = "Time's up!";
if (difference > 0) {
const parts = {
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
minutes: Math.floor((difference / 1000 / 60) % 60),
seconds: Math.floor((difference / 1000) % 60),
};
remaining = Object.keys(parts).map(part => {
return `${parts[part]} ${part}`;
}).join(" ");
}
document.getElementById("countdown").innerHTML = remaining;
}
countDownTimer();
Now your countdown time is ready to be displayed on your HTML page. You may notice that the time doesn’t update. There’s still more code to add to make sure that the countdown timer automatically updates.
Thus far, you’ve calculated the time difference between the current time and the time that your countdown expires. You’ve broken that time into hours, minutes, and seconds, and then updated the page with the time remaining. However, the timer will not currently update automatically.
Without additional logic to update the page periodically, the timer is stuck in place until the next time the page is loaded. Without an update, it’s hard to describe it as a timer.
This can be solved by using the setInterval
method. Use the setInterval
method and pass in countdownTimer
and 1000
as its two arguments:
countdownTimer();
setInterval(countdownTimer, 1000);
Now, countdownTimer
will run every second (or 1000ms) and update the timer’s display.
In this tutorial, you created a countdown timer using pure JavaScript. You used methods like .map()
and setInterval
. If you would like to gain a more in-depth knowledge of these methods, How To Use .map()
to Iterate Through Array Items in JavaScript and Scheduling Tasks in JavaScript Using setTimeout
and setInterval
can be helpful.
With this project complete, a great next step is to add React to the mix. This How to Create a Countdown Timer with React Hooks tutorial is a great place to start.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!