Section 1: Getting started and the first two projects
Project 1: a focus timer, part one
Our first project is a focus timer that counts down 25 minutes of work and then 5 minutes of break. Open 01-timer/index.html. The HTML contains a heading, a large time display and two buttons: Start and Reset.
<main class="timer">
<h1 id="mode">Focus</h1>
<p id="time" class="time" aria-live="off">25:00</p>
<button id="start" type="button">Start</button>
<button id="reset" type="button">Reset</button>
</main>
Selecting elements
In app.js, grab the elements once at the top:
const modeEl = document.querySelector("#mode");
const timeEl = document.querySelector("#time");
const startBtn = document.querySelector("#start");
const resetBtn = document.querySelector("#reset");
State and formatting
const DURATIONS = { focus: 25 * 60, break: 5 * 60 };
const state = {
mode: "focus",
secondsLeft: DURATIONS.focus,
running: false,
};
function formatTime(total) {
const m = Math.floor(total / 60);
const s = total % 60;
return `${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
}
padStart adds leading zeros so the display always shows two digits, for example 04:09.
Render
function render() {
modeEl.textContent = state.mode === "focus" ? "Focus" : "Break";
timeEl.textContent = formatTime(state.secondsLeft);
startBtn.textContent = state.running ? "Pause" : "Start";
document.title = `${formatTime(state.secondsLeft)} ${modeEl.textContent}`;
}
render();
Updating document.title shows the remaining time in the browser tab, which is handy when the tab is in the background.
A note on the time element
We set aria-live="off" on the time display on purpose. If it announced every second, screen reader users would hear a constant stream of numbers. Instead, in the next lesson we announce only when a session starts or ends, using a separate status message.
Check your work
Open the page. You should see "Focus" and "25:00", and the tab title should show the time. Nothing happens when you click Start yet. That is next: making time pass.