JavaScript Timer Thinking

Learn setTimeout, setInterval, clearTimeout, clearInterval, countdowns, clocks, traffic lights, animations, typing games, progress bars, toast messages, quiz timers, and real-world timer logic.

Level 0

Why Do We Need Timers?

JavaScript normally runs code immediately from top to bottom.

console.log("First");
console.log("Second");
console.log("Third");

Output:

First
Second
Third

But real websites often need to do something later or again and again.

Do Something Later

Show a message after 3 seconds.

Use setTimeout().

Do Something Repeatedly

Update a clock every second.

Use setInterval().

Stop a Delayed Task

Cancel a message before it appears.

Use clearTimeout().

Stop a Repeating Task

Stop a counter, clock, or animation.

Use clearInterval().

Timer: A timer schedules code according to time. JavaScript timers do not freeze the whole page. They schedule work and allow the page to continue.
Level 1

setTimeout()

setTimeout() runs a function once after a delay.

Basic Syntax

setTimeout(function() {
  // code to run later
}, delayInMilliseconds);

1000 milliseconds = 1 second.

Simple Example

setTimeout(function() {
  console.log("Hello after 3 seconds");
}, 3000);

Arrow Function Example

setTimeout(() => {
  console.log("This also runs later");
}, 2000);

Live Demo: Delayed Message

Click the button. The message will appear after 3 seconds.

Waiting for action...
Important: setTimeout() does not pause JavaScript. It schedules the function and lets the rest of the code continue.
console.log("A");

setTimeout(() => {
  console.log("B");
}, 2000);

console.log("C");

Output:

A
C
B
Level 2

setInterval()

setInterval() runs a function again and again after a fixed delay.

Basic Syntax

setInterval(function() {
  // code to repeat
}, delayInMilliseconds);

Example

setInterval(() => {
  console.log("Repeating every second");
}, 1000);

Live Demo: Counter

This counter increases every second.

0
Counter is stopped.
Warning: If you start many intervals without stopping old ones, the page may behave strangely because multiple timers will run together.
Level 3

Stopping Timers

When we create a timer, JavaScript gives us an ID. We can use this ID to stop the timer.

Stopping setTimeout

let timeoutId = setTimeout(() => {
  console.log("This may run later");
}, 5000);

clearTimeout(timeoutId);

Stopping setInterval

let intervalId = setInterval(() => {
  console.log("Repeating");
}, 1000);

clearInterval(intervalId);

Live Demo: Cancel a Delayed Message

No timeout started.
Full Code Example 1

Complete Page: Show Message After 3 Seconds

This is the smallest complete HTML page using setTimeout().

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>setTimeout Message</title>
</head>
<body>
  <h1>setTimeout Example</h1>

  <button onclick="showLater()">Show Message After 3 Seconds</button>

  <p id="message">Waiting...</p>

  <script>
    function showLater() {
      document.getElementById("message").textContent = "Timer started...";

      setTimeout(function () {
        document.getElementById("message").textContent =
          "Hello! I appeared after 3 seconds.";
      }, 3000);
    }
  </script>
</body>
</html>
Full Code Example 2

Complete Page: Cancel a setTimeout

A delayed action can be cancelled using clearTimeout().

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Cancel Timeout</title>
</head>
<body>
  <h1>Cancel setTimeout Example</h1>

  <button onclick="startTimer()">Start 5 Second Timer</button>
  <button onclick="cancelTimer()">Cancel Timer</button>

  <p id="result">No timer started.</p>

  <script>
    let timerId = null;

    function startTimer() {
      document.getElementById("result").textContent =
        "Timer started. Message will appear after 5 seconds.";

      timerId = setTimeout(function () {
        document.getElementById("result").textContent =
          "The timer completed.";
        timerId = null;
      }, 5000);
    }

    function cancelTimer() {
      if (timerId === null) {
        document.getElementById("result").textContent =
          "There is no active timer to cancel.";
        return;
      }

      clearTimeout(timerId);
      timerId = null;

      document.getElementById("result").textContent =
        "Timer cancelled.";
    }
  </script>
</body>
</html>
Full Code Example 3

Complete Page: Repeating Counter

This page uses setInterval() and clearInterval().

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Counter with setInterval</title>
</head>
<body>
  <h1>Counter</h1>

  <h2 id="counter">0</h2>

  <button onclick="startCounter()">Start</button>
  <button onclick="stopCounter()">Stop</button>
  <button onclick="resetCounter()">Reset</button>

  <p id="status">Stopped.</p>

  <script>
    let count = 0;
    let intervalId = null;

    function startCounter() {
      if (intervalId !== null) {
        document.getElementById("status").textContent =
          "Already running.";
        return;
      }

      document.getElementById("status").textContent = "Running...";

      intervalId = setInterval(function () {
        count++;
        document.getElementById("counter").textContent = count;
      }, 1000);
    }

    function stopCounter() {
      clearInterval(intervalId);
      intervalId = null;
      document.getElementById("status").textContent = "Stopped.";
    }

    function resetCounter() {
      stopCounter();
      count = 0;
      document.getElementById("counter").textContent = count;
      document.getElementById("status").textContent = "Reset.";
    }
  </script>
</body>
</html>
Full Code Example 4

Complete Page: Digital Clock

A digital clock updates every second.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Digital Clock</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      text-align: center;
      padding: 40px;
    }

    #clock {
      font-size: 48px;
      font-weight: bold;
    }
  </style>
</head>
<body>
  <h1>Digital Clock</h1>
  <div id="clock">--:--:--</div>

  <script>
    function updateClock() {
      const now = new Date();
      document.getElementById("clock").textContent =
        now.toLocaleTimeString();
    }

    updateClock();
    setInterval(updateClock, 1000);
  </script>
</body>
</html>
Full Code Example 5

Complete Page: Countdown Timer

A countdown is one of the most useful setInterval() projects.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Countdown Timer</title>
</head>
<body>
  <h1>Countdown Timer</h1>

  <input id="secondsInput" type="number" value="10" min="1" />

  <button onclick="startCountdown()">Start</button>
  <button onclick="stopCountdown()">Stop</button>

  <h2 id="display">10</h2>
  <p id="status">Ready.</p>

  <script>
    let seconds = 10;
    let intervalId = null;

    function startCountdown() {
      if (intervalId !== null) {
        document.getElementById("status").textContent =
          "Countdown already running.";
        return;
      }

      seconds = Number(document.getElementById("secondsInput").value);

      if (seconds <= 0 || Number.isNaN(seconds)) {
        document.getElementById("status").textContent =
          "Enter a positive number.";
        return;
      }

      document.getElementById("display").textContent = seconds;
      document.getElementById("status").textContent = "Running...";

      intervalId = setInterval(function () {
        seconds--;
        document.getElementById("display").textContent = seconds;

        if (seconds <= 0) {
          clearInterval(intervalId);
          intervalId = null;
          document.getElementById("status").textContent = "Time over!";
        }
      }, 1000);
    }

    function stopCountdown() {
      clearInterval(intervalId);
      intervalId = null;
      document.getElementById("status").textContent = "Stopped.";
    }
  </script>
</body>
</html>
Full Code Example 6

Complete Page: Auto-Hide Toast Message

Toast messages are small notifications. They often disappear automatically using setTimeout().

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Toast Message</title>
  <style>
    #toast {
      position: fixed;
      right: 20px;
      bottom: 20px;
      background: black;
      color: white;
      padding: 14px 18px;
      border-radius: 10px;
      transform: translateY(150%);
      transition: transform 0.3s ease;
    }

    #toast.show {
      transform: translateY(0);
    }
  </style>
</head>
<body>
  <h1>Toast Message Example</h1>

  <button onclick="showToast()">Show Toast</button>

  <div id="toast">Saved successfully!</div>

  <script>
    let toastTimer = null;

    function showToast() {
      const toast = document.getElementById("toast");

      toast.classList.add("show");

      clearTimeout(toastTimer);

      toastTimer = setTimeout(function () {
        toast.classList.remove("show");
      }, 3000);
    }
  </script>
</body>
</html>
Full Code Example 7

Complete Page: Typing Game

This game changes the word every 3 seconds.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Typing Game</title>
</head>
<body>
  <h1>Typing Game</h1>

  <h2 id="word">apple</h2>

  <input id="typed" type="text" placeholder="Type the word" />

  <button onclick="startGame()">Start Game</button>
  <button onclick="stopGame()">Stop Game</button>

  <p>Score: <span id="score">0</span></p>
  <p id="status">Ready.</p>

  <script>
    const words = ["apple", "mango", "timer", "clock", "button"];
    let currentWord = "apple";
    let score = 0;
    let intervalId = null;

    function pickWord() {
      const index = Math.floor(Math.random() * words.length);
      currentWord = words[index];
      document.getElementById("word").textContent = currentWord;
      document.getElementById("typed").value = "";
      document.getElementById("typed").focus();
    }

    function startGame() {
      if (intervalId !== null) {
        return;
      }

      score = 0;
      document.getElementById("score").textContent = score;
      document.getElementById("status").textContent = "Game running.";

      pickWord();

      intervalId = setInterval(function () {
        const typed = document.getElementById("typed").value.trim();

        if (typed === currentWord) {
          score++;
          document.getElementById("score").textContent = score;
        }

        pickWord();
      }, 3000);
    }

    function stopGame() {
      clearInterval(intervalId);
      intervalId = null;
      document.getElementById("status").textContent = "Game stopped.";
    }
  </script>
</body>
</html>
Full Code Example 8

Complete Page: Progress Bar

A progress bar grows repeatedly until it reaches 100%.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Progress Bar</title>
  <style>
    .box {
      width: 100%;
      height: 28px;
      background: #ddd;
      border-radius: 999px;
      overflow: hidden;
    }

    #bar {
      height: 100%;
      width: 0%;
      background: green;
    }
  </style>
</head>
<body>
  <h1>Progress Bar</h1>

  <div class="box">
    <div id="bar"></div>
  </div>

  <p id="status">0%</p>

  <button onclick="startProgress()">Start</button>
  <button onclick="resetProgress()">Reset</button>

  <script>
    let width = 0;
    let intervalId = null;

    function startProgress() {
      if (intervalId !== null) {
        return;
      }

      intervalId = setInterval(function () {
        width++;

        document.getElementById("bar").style.width = width + "%";
        document.getElementById("status").textContent = width + "%";

        if (width >= 100) {
          clearInterval(intervalId);
          intervalId = null;
          document.getElementById("status").textContent = "Complete!";
        }
      }, 50);
    }

    function resetProgress() {
      clearInterval(intervalId);
      intervalId = null;
      width = 0;
      document.getElementById("bar").style.width = "0%";
      document.getElementById("status").textContent = "0%";
    }
  </script>
</body>
</html>
Full Code Example 9

Complete Page: Quiz Timer

Each quiz question can have a timer. Here we make a 10-second quiz timer.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Quiz Timer</title>
</head>
<body>
  <h1>Quiz Timer</h1>

  <h2>What does setInterval do?</h2>

  <button onclick="answer(false)">Runs code once</button>
  <button onclick="answer(true)">Runs code repeatedly</button>

  <h3>Time Left: <span id="time">10</span></h3>
  <p id="result">Choose an answer.</p>

  <script>
    let timeLeft = 10;
    let intervalId = setInterval(function () {
      timeLeft--;
      document.getElementById("time").textContent = timeLeft;

      if (timeLeft <= 0) {
        clearInterval(intervalId);
        document.getElementById("result").textContent =
          "Time over!";
      }
    }, 1000);

    function answer(isCorrect) {
      clearInterval(intervalId);

      if (isCorrect) {
        document.getElementById("result").textContent = "Correct!";
      } else {
        document.getElementById("result").textContent = "Wrong answer.";
      }
    }
  </script>
</body>
</html>
Full Code Example 10

Complete Page: Debounced Search

Debouncing means waiting until the user stops typing. This is useful for search boxes.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Debounced Search</title>
</head>
<body>
  <h1>Debounced Search</h1>

  <input id="search" type="text" placeholder="Type to search..." />

  <p id="output">Search result will appear here.</p>

  <script>
    const searchInput = document.getElementById("search");
    const output = document.getElementById("output");

    let timerId = null;

    searchInput.addEventListener("input", function () {
      output.textContent = "Typing...";

      clearTimeout(timerId);

      timerId = setTimeout(function () {
        output.textContent =
          "Searching for: " + searchInput.value;
      }, 600);
    });
  </script>
</body>
</html>
Live Project 1

Digital Clock

A digital clock is a perfect use case for setInterval(). The time must update again and again.

setInterval(() => {
  let now = new Date();
  console.log(now.toLocaleTimeString());
}, 1000);

Live Clock

--:--:--
Live Project 2

Countdown Timer

A countdown starts from a number and decreases every second.

Countdown

10
Ready.
Live Project 3

Traffic Light

We can use setInterval() to keep changing the active light.

Traffic Light Simulation

Traffic light is ready.
Live Project 4

Simple Animation

Before modern animation tools, many animations used setInterval().

Moving Box

Box is ready.
For professional animation, requestAnimationFrame() is usually better. But setInterval() is excellent for learning timer logic.
Live Project 5

Toast Message

Click the button. A toast message appears and hides automatically after 3 seconds.

The toast will appear at the bottom-right corner.
Live Project 6

Progress Bar

This progress bar uses setInterval() and stops at 100%.

0%
Live Project 7

Typing Game

A new word appears every 3 seconds. Type the word before it changes.

timer
Score: 0
Live Project 8

Quiz Timer

This quiz gives you 10 seconds to answer.

Question: What does setTimeout do?

Click restart to begin. Time left: 10
Live Project 9

Debounced Search

The search result updates only after you stop typing for 600 milliseconds.

Search result will appear here.
Level 10

Common Mistakes

Mistake 1: Calling the Function Immediately

// Wrong
setTimeout(sayHello(), 1000);

// Correct
setTimeout(sayHello, 1000);

In the wrong version, sayHello() runs immediately. In the correct version, JavaScript receives the function and runs it later.

Mistake 2: Forgetting to Stop an Interval

let id = setInterval(() => {
  console.log("Running forever");
}, 1000);

// Stop it when needed
clearInterval(id);

Mistake 3: Starting the Same Interval Many Times

If a user clicks the start button 10 times, 10 intervals may start. Always check whether an interval is already running.

if (intervalId === null) {
  intervalId = setInterval(work, 1000);
}

Mistake 4: Thinking 0 Milliseconds Means Immediate

console.log("Start");

setTimeout(() => {
  console.log("Timer");
}, 0);

console.log("End");

Output:

Start
End
Timer
Infinity Level

How JavaScript Actually Handles Timers

JavaScript uses an event loop. Timer functions are not guaranteed to run at the exact millisecond. They run when the main thread is free.

Even with 0 milliseconds, setTimeout() waits until the current code finishes.

setTimeout Recursion

Sometimes, instead of setInterval(), programmers use repeated setTimeout().

function repeatWork() {
  console.log("Work done");

  setTimeout(repeatWork, 1000);
}

repeatWork();

This calls the function, waits 1 second, then calls it again.

This is useful when the next delay depends on the result of the previous task.
Function Purpose Runs How Many Times? Stopped By
setTimeout() Run code after a delay Once clearTimeout()
setInterval() Run code repeatedly Again and again clearInterval()
Practice

Practice Tasks

Beginner

Show “Welcome” after 2 seconds using setTimeout().

Beginner Plus

Print numbers from 1 to 10, one number every second.

Intermediate

Make a countdown from 30 to 0 and show “Time over”.

Advanced

Make a quiz where each question has a 10-second timer.

Advanced Plus

Make a progress bar that pauses and resumes.

Infinity

Make a typing game where a new word appears every 3 seconds.

Embedded Editor

Practice in the HTML Editor

Use this editor to copy any full-code example and run it.

Saved successfully!