I am trying to make a program that displays a traffic light sequence. I have made a mistake in the code so it doesn’t get past showing the red light when the “starts sequence” button is clicked. if you can see where I went wrong please help me get it working.
I have used functions to change the display of the different lights. when the start sequence button is clicked the change function should call each function (stop,ready,go) which change the brightness of the lights in order from red to amber to green and back.
function change() { setTimeout(stop, 2000); setTimeout(ready, 2000); setTimeout(go, 2000); setTimeout(ready, 2000); setTimeout(stop, 2000); } function stop() { aimg = document.getElementById("a"); bimg = document.getElementById("b"); cimg = document.getElementById("c"); aimg.style.filter = "brightness(2)"; bimg.style.filter = "brightness(0)"; cimg.style.filter = "brightness(0)"; } function go() { aimg = document.getElementById("a"); bimg = document.getElementById("b"); cimg = document.getElementById("c"); aimg.style.filter = "brightness(0)"; bimg.style.filter = "brightness(0)"; cimg.style.filter = "brightness(2)"; } function ready() { aimg = document.getElementById("a"); bimg = document.getElementById("b"); cimg = document.getElementById("c"); aimg.style.filter = "brightness(0)"; bimg.style.filter = "brightness(2)"; cimg.style.filter = "brightness(0)"; }
.container { height: 450px; width: 200px; border: 5px solid; ; } .top { position: absolute; top: 30px; left: 35px; } .middle { position: absolute; top: 175px; left: 35px; } .bottom { position: absolute; top: 320px; left: 35px; }
<html> <body> <div class="container"></div> <button id="traffic" onClick="change()">start sequence</button><br> <div class="top"> <img src="aRed.png" alt="Red" id="a"><br> </div> <div class="middle"> <img src="bAmber.png" alt="Amber" id="b"><br> </div> <div class="bottom"> <img src="cGreen.png" alt="Green" id="c"><br> </div> </body> </html>
Advertisement
Answer
You’re calling all setTimeout
at the same time, so they all trigger after 2 seconds. You could solve it by calling each timeout after the previous one has finished. Also, you don’t need to find the elements again in each function call.
let aimg = document.getElementById("a"); let bimg = document.getElementById("b"); let cimg = document.getElementById("c"); function change() { setTimeout(stop, 2000); } function stop() { aimg.style.filter = "brightness(2)"; bimg.style.filter = "brightness(0)"; cimg.style.filter = "brightness(0)"; setTimeout(ready, 2000); } function ready() { aimg.style.filter = "brightness(0)"; bimg.style.filter = "brightness(2)"; cimg.style.filter = "brightness(0)"; setTimeout(go, 2000); } function go() { aimg.style.filter = "brightness(0)"; bimg.style.filter = "brightness(0)"; cimg.style.filter = "brightness(2)"; setTimeout(stop, 2000); }
Bear in mind that if you call change()
more than once, you’ll start multiple sequences. You could prevent that by storing a interval id for each of the three timeouts
readyTimeout = setTimeout(ready, 2000);
And then canceling them all when the button is pressed:
clearTimeout(readyTimeout);