If you're like me, this exercise threw you at first (and if it came naturally, feel free to pat yourself on the back you deserve it). Here's the right way to do it: have the button's onClick call the following function:
function ringBell()
{
var timer1 = setTimeout("window.document.the_form.the_text.value='3 seconds!';",3000);
var timer2 = setTimeout("window.document.the_form.the_text.value='6 seconds!';",6000);
var timer3 = setTimeout("window.document.the_form.the_text.value='9 seconds!';",9000);
}
It says, "write '3 seconds' three seconds from now, '6 seconds' six seconds from now, and '9 seconds' nine seconds from now." Makes sense, right?
However, the following doesn't work:
function doDumbTimer()
{
var timer1 = setTimeout("window.document.the_form.the_text.value='3 seconds!';",3000);
var timer2 = setTimeout("window.document.the_form.the_text.value='6 seconds!';",3000);
var timer3 = setTimeout("window.document.the_form.the_text.value='9 seconds!';",3000);
}
Notice that if you wait three seconds, one of the three timing messages
mysteriously appears in the text box and then just stays there. In the bad
code above, each of the setTimeouts get executed consecutively,
(i.e., it's saying, "write '3 seconds' three seconds from now, '6 seconds'
three seconds from now, and '9 seconds' three seconds from now"). So after
three seconds pass, all three things happen, and you end up with whichever
one happens to fire last definitely not what you want.
Once you understand it, setTimeout() is quite easy to use. However, one thorny question does arise: How can you make a timer that does something every two seconds, from now until forever? For example:
Don't worry about the stop timer button for now, I'll cover clearTimeouts in a bit. Just think about how you would get this timer to loop indefinitely. It's actually a very important question, and not just a silly exercise. As I mentioned earlier, when you want to make stuff move slowly across the screen using dynamic HTML, execute a small timed loop: "Move it over a little, wait, move it more, wait ... and so on."
Are you thinking about it?
Well, the answer's not an easy one. You can't just have a function, like the one above, that changes the text box every two seconds, like so:
function theTimer()
{
var timer1 = setTimeout("changeTextBoxTo(2);",2000);
var timer2 = setTimeout("changeTextBoxTo(4);",4000);
var timer3 = setTimeout("changeTextBoxTo(6);",6000);
var timer4 = setTimeout("changeTextBoxTo(8);",8000);
var timer5 = setTimeout("changeTextBoxTo(10);",10000);
.
.
.
}
Because, well, you can see why not: If you want something to loop infinitely, and you used this method, you'd have to have infinite lines of code. Among other problems, like serious carpal tunnel syndrome, it would take a really long time to download a page with an never-ending number of JavaScript lines, so that's not really an option.
This doesn't work either, even though it looks sort of cool:
function theTimer()
{
the_time = 0;
hellIsHot = true;
while (hellIsHot == true)
{
the_time += 2;
var timer = setTimeout("changeTextBoxTo(the_time);", the_time*1000);
}
}
Study this thing for a while to see what I'm getting at. But don't try running it. The results will make you very unhappy. Let's do a few iterations of the "while" loop:
Iteration 1
while (hellIsHot == true) : Yup, hell sure is hot.
the_time += 2 : so now the_time = 2
var time = setTimeout("changeTextBoxTo(2);", 2000) : so, two seconds from now, the textbox will change to "2."
That's what we want.
Iteration 2
while (hellIsHot == true) : Verily, hell is still hot.
the_time += 2 : so now the_time = 4
var time = setTimeout("changeTextBoxTo(4);", 4000) : so, four seconds from now, the textbox will change to "4." OK, that's good.
Iteration 3
while (hellIsHot == true) : Nope, hell isn't getting any colder.
the_time += 2 : so now the_time = 6
var time = setTimeout("changeTextBoxTo(6);", 6000) : so, six seconds from now, the textbox will change to "6." Fine.
Iteration 4
while (hellIsHot == true) : OK already! It's hot!
yadda
yadda yadda
You get the picture. It looks like this code should do the right thing. Unfortunately, it doesn't. Instead it creates this unending loop, scheduling setTimeouts until hell freezes over. There are two problems here. First, while it's in the loop, your browser can't do anything else. It'll basically freeze, spinning its wheels, scheduling setTimeouts forever. Second, every time a setTimeout is scheduled, the browser has to remember what you're scheduling and when you want it to run. Eventually your browser will run out of memory. When this happens, your browser will crash, or your computer will crash, or you'll get mad and never write another line of JavaScript again.
Not good at all.
Fortunately, there is a way to write a successful looping timer.