Lesson 10 of 11
Study Timer
Code that runs when nobody is touching the page. Once a second, until you stop it.
What you will learn
- setInterval
- clearInterval
- Remainder with %
- padStart
- Stopping a second timer
- Disabled buttons
Before you start
Rock Paper Scissors. There you kept a score in a variable between clicks. Here the page keeps counting between clicks, with nobody pressing anything.
What this page does
- Click Start. The clock counts down once a second.
- Start switches itself off while it runs. Pause switches itself on.
- Click 1 min and it resets to one minute, so you can watch it reach zero.
setInterval, and the number it hands back
ticking = setInterval(tick, 1000);That asks the browser to run tick every 1000 milliseconds, which is once a second, for ever. The function that started it finishes straight away. The repeating carries on without it.
clearInterval(ticking);
ticking = null;clearInterval takes that number and ends the job. Setting ticking back to null afterwards is what lets the rest of the file tell whether anything is running. That one variable answers the question, so nothing else has to keep track of it separately.
The two numbers
The first one is the second argument to setInterval. Change it and the clock still takes one second off per tick, so the whole timer speeds up or slows down.
1000 is one second. Set it to 200 and press Start. The timer now runs five times too fast, because it still takes one second off every time.
Set this to 1 to test the end of the timer without waiting twenty minutes.
The bug this lesson exists to teach
function start() {
if (ticking !== null) return;
...
}Without that line, clicking Start twice makes two repeating jobs. Both take a second off the same number, so the clock runs at double speed. Click it five times and it runs five times too fast.
It is worse than looking wrong. The first job's number was overwritten by the second, so nothing can ever stop the first one. Pause stops one job and the other keeps going.
Every setInterval in your code needs an answer to one question: what stops this from being started twice? Here the answer is one if. That is usually all it takes.
Seconds, turned into a clock
The code counts in seconds and nothing else. Minutes and colons are for showing a person, and that happens in one place.
function asClock(seconds) {
const minutes = Math.floor(seconds / 60);
const rest = seconds % 60;
return String(minutes).padStart(2, "0") + ":" + String(rest).padStart(2, "0");
}| For 90 seconds | Gives | Because |
|---|---|---|
Math.floor(90 / 60) | 1 | How many whole minutes fit. floor throws away the rest |
90 % 60 | 30 | The remainder. What is left over |
String(8).padStart(2, "0") | "08" | A zero in front, so the clock never reads 1:8 |
Keeping one unit inside the code and converting only when you show it is a habit worth building. Every sum in this file is a sum about seconds, so none of them has to think about minutes at all.
Build it step by step
Get one second to pass before you build anything around it.
Make the page
Make
index.htmlwith a<p id="clock">, and Start, Pause and Reset buttons. Put the<script>tag at the end.Prove setInterval runs
Before anything else, write this and reload. Open the console with F12. A line appears every second, and it keeps appearing. Watch it for ten seconds, then reload the page to stop it.
setInterval(function () { console.log("tick"); }, 1000);Count down in the console
Add
secondsLeftand take one off inside the interval. Log it. You now have a countdown with no page attached to it.Put it on the page
Write
asClockand ashowfunction. Callshow()from inside the tick. The clock now moves.Add Start and Pause
Move the
setIntervalinto astartfunction and connect it to the button. WritestopwithclearIntervaland connect Pause. Test both.Find the double-start bug
Click Start three times. The clock speeds up. Add
if (ticking !== null) return;at the top ofstartand try again. This step is the lesson.Stop at zero
In
tick, whensecondsLeftreaches 0, set it to 0 and callstop(). Without this the clock counts into negative numbers.Switch the buttons on and off
Set
disabledon both buttons insideshow, worked out fromticking. Never set it inside a click handler.
Try these changes
Make these changes in the files beside this guide. Each one only uses what this lesson has already covered. Tick each one when it works.
Check yourself
Three quick questions on this lesson. Get them all right to finish the lesson and earn a pack.
Loading your answers
Teacher's versionHow to run this lesson, what to check, and any answers. Students do not need this.
How to teach it
- Do step 2 on its own and leave it logging for a full ten seconds while you say nothing. Nobody is clicking and the page is still working. That silence is the idea of the lesson.
- Let them find the double-start bug themselves. Say only "click Start a few times" and wait. A student who has made a timer they cannot stop understands why the guard exists.
- Ask what
tickingholds when nothing is running.nullis the answer, and the fact that ONE variable answers both "what job" and "is anything running" is worth naming. - Set the tick-speed slider to 200 and ask why the timer is wrong. The interval fires five times a second and the code still takes a whole second off each time. Separating how often something runs from how much it changes is the useful idea.
- The seconds-only rule is worth saying out loud. Every number in the file is seconds. Minutes exist in exactly one function, at the moment of showing it.