Javascript Tutorial -- Pausing Execution with setTimeout()



Many, many years ago, when I was but a wee lad learning to write Basic programs on a TRS-80 Model III, I learned a programming technique that worked very well for the simple, slow programs I was writing at the time: when I needed to slow down a program, I would create a "for" loop and would adjust the number of iterations until I had an appropriate delay. This technique lasted through my Turbo Pascal 4.0 days, but as computers got faster and as compilers grew more intelligent, my simple timing mechanism ceased to function -- if the compiler actually included the otherwise pointless loop in the object code, it executed so fast that there was no appreciable delay, even for a million iterations.

However, modern programming languages recognize that sometimes it is necessary to slow down or stop execution for a period of time, for any of a number of reasons, and therefore most (if not all) modern languages provide a timer function. In Perl, for example, it is the sleep() function; in Javascript, we have "window.setTimeout()".

If you have used other scripting languages like Perl, Python or Bash, the Javascript setTimeout() method might confuse you at first, since it operates a little differently -- klunky, in fact, IMHO. For example, in Perl, if you want to print a line of text, pause for one second, then print another line of text, it would look like this:
        print "this is the first line of text\n";
        sleep(1);
        print "this is the second line of text\n";
      
In Javascript, however, the code to perform the exact same thing would look like this:
        ...
        document.write("this is the first line of text<br>")
        window.setTimeout('.write("this is the second line of text<br>")', 1000)
        ...
      
Whereas in the Perl script, the sleep() function was a separate line of code located at the precise point in the program flow where the pause was desired, the setTimeout() method is used to call the next step that should be delayed. It works, and using this method should not cause any major problems for anyone who has mastered the techniques we've discussed up to this point; I just didn't find it quite as intuitive as the Perl or Bash implementations.

So...now let's look at a practical application for the setTimeout() method. In Lesson 20, we created a Javascript program that would cycle through an array of images (or more precisely, an array of URLs that point to images) in response to clicks on a button. The problem with this script is that it required user input to load the next image. Suppose you wanted to make a slideshow that automatically loaded each image after, say, a five second delay?

No problem! In this case, we will write a function to load the next image, and call it from the setTimeout() method. There's only one catch -- after executing setTimeout() from the body of the main script, the Javascript program ends, so to continue cycling through images, the function we write will have to end with the setTimeout() method recursively calling our function again, like this:
        <html>
          <head>
            <title>
              setTimeout() example
            </title>
            <script type="text/javascript">
              <!--
                var i = 0

                function DisplayImage(i)
                  {
                    var Images = new Array()

                    i = i % 3

                    Images[0] = 'nd620008.jpg'
                    Images[1] = 'dscf0009.jpg'
                    Images[2] = 'dscf0033.jpg'

                    ImgSrc = 'http://www.gecko-ak.org/javascript/images/' + Images[i]
                    document.getElementById('ChangeMe').src = ImgSrc

                    // putting a setTimeout function at the end of the
                    // function allows the cycle to keep repeating.
                    // Note: I'm not sure why this must begin with "ID=" but it
                    // doesn't work without it...
                    ID=window.setTimeout('DisplayImage(++i)',5000)
                  }

                // the setTimeout function here starts the cycle when the page loads
                ID=window.setTimeout('DisplayImage(1)',5000)

                //-->
            </script>
          </head<
          <body>
            <p>
              <img src="http://www.gecko-ak.org/javascript/images/nd620008.jpg" id="ChangeMe">
            </p>
            <br>
          </body>
        </html>
      
Here is how this HTML document would look on-line, and here is a more complete script that uses the "innerHTML" method to include captions under the images and that caches images in the web browser for faster loading.