JavaScript Countdown Timer With Start Stop Buttons
Create a functional JavaScript Countdown Timer with Start and Stop buttons. This tool is perfect for showing time left for an event, a deadline, or a quiz timer. Below you can test the live demo and get the complete HTML, CSS, and JavaScript code snippet to use directly in your projects.
Demo: Countdown Timer
How to Use the Timer
Using the timer is simple. Enter a custom duration in seconds, click "Start" to begin, or "Pause" to take a break. The "Reset" button restores the initial time. A blinking display and sound effect signal when the time is up.
00:00:30
Features
- β±οΈ Displays time in HH:MM:SS format
- ποΈ Accepts custom time input (in seconds)
- βΆοΈ Start, βΈοΈ Pause, and π Resume controls
- π Reset button to restart the timer
- π Plays sound and visual blink on completion
- π Updates browser tab title with time left
Complete code HTML, CSS and JavaScript
<div id="timer">00:30</div>
<input id="time-input" type="number" min="1" placeholder="Seconds" value="30">
<button id="start-button">Start</button>
<button id="reset-button">Reset</button>
body {
font-family: Arial, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
#timer {
font-size: 48px;
margin: 20px 0;
color: #007bff;
}
input#time-input {
padding: 8px;
margin: 10px;
font-size: 1em;
width: 100px;
}
button {
padding: 10px 20px;
font-size: 18px;
margin: 10px;
border: none;
border-radius: 5px;
cursor: pointer;
}
button#start-button {
background-color: #28a745;
color: white;
}
button#reset-button {
background-color: #dc3545;
color: white;
}
.blink {
animation: blink 1s step-end infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
}
const DEFAULT_TIME = 30;
const TIMER_INTERVAL_MS = 1000;
const BLINK_CLASS = 'blink';
const BEEP_SOUND_URL = 'https://www.soundjay.com/buttons/beep-01a.mp3';
let countdownInterval;
let initialTime = DEFAULT_TIME;
let timeLeft = initialTime;
let isRunning = false;
const timerDisplay = document.getElementById("timer");
const startPauseBtn = document.getElementById("start-button");
const resetBtn = document.getElementById("reset-button");
const timeInput = document.getElementById("time-input");
const formatTime = seconds => {
const hrs = Math.floor(seconds / 3600);
const mins = Math.floor((seconds % 3600) / 60);
const secs = seconds % 60;
return [hrs, mins, secs].map(unit => String(unit).padStart(2, '0')).join(':');
};
const updateDisplay = seconds => {
const formatted = formatTime(seconds);
timerDisplay.textContent = formatted;
document.title = `Timer: ${formatted}`;
};
const playEndSound = () => {
const beep = new Audio(BEEP_SOUND_URL);
beep.play().catch(console.error);
};
const onTimeEnd = () => {
isRunning = false;
startPauseBtn.textContent = 'Start';
startPauseBtn.disabled = false;
playEndSound();
timerDisplay.classList.add(BLINK_CLASS);
// callback_time_end(); // hook for callback
};
const startCountdown = () => {
isRunning = true;
startPauseBtn.textContent = 'Pause';
startPauseBtn.disabled = false;
countdownInterval = setInterval(() => {
if (timeLeft > 0) {
timeLeft--;
updateDisplay(timeLeft);
} else {
clearInterval(countdownInterval);
onTimeEnd();
}
}, TIMER_INTERVAL_MS);
};
const pauseCountdown = () => {
clearInterval(countdownInterval);
isRunning = false;
startPauseBtn.textContent = 'Resume';
};
const handleStartPause = () => {
if (isRunning) {
pauseCountdown();
} else {
if (timeInput?.value) {
const newTime = parseInt(timeInput.value, 10);
if (isNaN(newTime) || newTime <= 0) {
alert("Please enter a valid time in seconds.");
return;
}
initialTime = newTime;
if (timeLeft === 0 || timeLeft === DEFAULT_TIME) {
timeLeft = initialTime;
updateDisplay(timeLeft);
}
}
startCountdown();
}
};
const resetCountdown = () => {
clearInterval(countdownInterval);
isRunning = false;
timeLeft = initialTime;
updateDisplay(timeLeft);
startPauseBtn.textContent = 'Start';
startPauseBtn.disabled = false;
timerDisplay.classList.remove(BLINK_CLASS);
};
const handleTimeInputChange = () => {
if (isRunning) return;
const newTime = parseInt(timeInput.value, 10);
if (!isNaN(newTime) && newTime > 0) {
initialTime = newTime;
timeLeft = initialTime;
updateDisplay(timeLeft);
}
};
updateDisplay(timeLeft);
startPauseBtn.addEventListener("click", handleStartPause);
resetBtn.addEventListener("click", resetCountdown);
timeInput.addEventListener("change", handleTimeInputChange);
Related: