Using Timers In JavaScript

Create timed or looping events in your Web pages with the Window object.

Time Bomb

Some of the most common and beneficial uses of JavaScript involve timer functions. These functions are used to run client-side code at predefined intervals, thereby making it possible to add a new dimension - time - to your Web pages. By using JavaScript's timing functions, you can run a command after a specified delay has passed, loop events to run over and over again at predefined times, and synchronize multiple events on a timeline.

Over the course of this article, I'll be exploring the various timing functions available in JavaScript, together with examples of how they can be used to create timed events in an HTML document. I'll introduce you to the setTimeout(), clearTimeout(), setInterval() and clearInterval() functions, and also show you how to use them to create a variety of different client-side applications, including a tickertape, a timed slideshow, and a countdown clock. So come on in - if you're new to JavaScript, you're going to find this article to be quite an eye-opener!

Window Washer

Let's start at the top, with the setTimeout() and clearTimeout() methods. These methods belong to the Window object, and are commonly used to run a particular piece of code after a pre-defined interval has passed. Consider the following example, which illustrates:

<script language="JavaScript">
var t = window.setTimeout('alert("5 seconds have passed since you loaded this page")', 5000);
</script>

In this case, the setTimeout() method is used to run the function 5000 milliseconds (5 seconds). Thus, there are always two arguments to the setTimeout() method - the first is the code to run, and the second is the amount of time to wait before running it.

Here's another, more useful example.

<script language="JavaScript">
var t = setTimeout('window.close()', 30000);
</script>

In this one, the window (which we'll assume has been popped open from some other parent window) closes automatically 30 seconds after it opens.

Just as you can set a timeout, you can also clear it with the clearTimeout() method. This method is used to remove a timeout previously declared with setTimeout(). Since there may be multiple calls to setTimeout() in the same document, it is mandatory to provide clearTimeout() with a reference so that it knows which timeout to clear. The following variant of the example above demonstrates:

<script language="JavaScript">
var t = window.setTimeout('window.close()', 30000);
window.clearTimeout(t);
</script>

In this case, the window will never close, because the clearTimeout() method will cancel the timeout previously created with setTimeout().

If you want to really obfuscate, you can clear a timeout after a specified interval, by wrapping the call to clearTimeout() in a call to setTimeout():

<script language="JavaScript">
var t = window.setTimeout('window.close()', 30000);
var c = window.setTimeout('window.clearTimeout(t)', 10000);
</script>

In this case too, the window will never close, because the first timeout will be cancelled 10 seconds in by the call to clearTimeout() in the second.

New Year Blues

Here's another example, this one containing two timers. The first one is set to close the window after 30 seconds. However, 10 seconds in, the second one will activate and ask the user to confirm the timeout. If the user does not confirm it, the timeout will be cancelled.

<script language="JavaScript">
// set timeout for window to close
var win = setTimeout('window.close()', 30000);

// set timeout for user input
var check = setTimeout('checkStatus()', 10000);

// ask if user wants window to close
// if no, clear timeout for window to close
function checkStatus()
{
    if(!window.confirm("This window will shut in 20 seconds. Is that OK?"))
    {
        window.clearTimeout(win);
    }
}
</script>

Note that after the confirm() dialog bog is displayed and while it is waiting for a user click, all timers are suspended.

Here's another example, this one using the setTimeout() method to create a countdown clock. Take a look:

<html>
<head>
<script language="JavaScript">
var i=10;

function countDown()
{
    if(i > 0)
    {
        document.forms[0].elements[0].value=i;
        i = i-1;
        var c = window.setTimeout("countDown()", 1000);
    }
    else
    {
        alert("Happy New Year!");
    }
}
</script>
</head>

<body onLoad="countDown()">

<form>
<input type="text" name="counter" size="3">
</form>

</body>
</html>

In this case, I'm using the setTimeout() method to call itself in a loop every second, and updating the value of the countdown clock on every iteration of the loop. When the countdown hits 0, an alert box is displayed

A Decent Interval

Next up, the setInterval() and clearInterval() methods. The main difference between these methods and the ones on the previous page is this: the setTimeout() and clearTimeout() methods are used to run a particular piece of code once after a pre-defined interval has passed, while the setInterval() and clearInterval() methods are used to run a piece of code over and over again, with a pre-defined interval between successive runs.

Consider the following example, which illustrates:

<script language="JavaScript">
var y = window.setInterval('alert("Yoohoo!")', 2000);
</script>

In this case, the alert() box will keep appearing, once every 2 seconds. Thus, there are always two arguments to the setInterval() method - the first is the code to run, and the second is the amount of time between successive runs.

Here's another, more interesting example - creating a scrolling tickertape in the window's status bar:

<script language="JavaScript">
// ticket-tape message
var message = " A blue pig jumped over the yellow moon ";

// add and remove characters from the message
function tickerTape()
{
    window.status = message;
    message = message.substring(1, message.length) + message.substring(0, 1);
}

// start the ball rolling
window.setInterval("tickerTape()", 150);
</script>

In this case, I've created the appearance of a moving tickertape by taking one character off the beginning of the message string and adding it to the end. Each time the tickerTape() function is called, the first character of the string is deleted and added to the end of the string, simulating a scrolling ticker-tape. The setInterval() function takes care of calling the tickerTape() function over and over again, once every 150 milliseconds. Finally, the "status" property is used to assign the result at each stage to the browser's status bar.

Just as you can set an interval, you can also clear it with the clearInterval() method. Here too, you must provide clearInterval() with a reference so that it knows which interval to clear. The following variant of the example above demonstrates:

<html>
<head>
<script language="JavaScript">
// ticket-tape message
var message = " A blue pig jumped over the yellow moon ";

// add and remove characters from the message
function tickerTape()
{
    window.status = message;
    message = message.substring(1, message.length) + message.substring(0, 1);
}

// start the ball rolling
var s = window.setInterval("tickerTape()", 150);
</script>
</head>

<body>

<form>
<input type="button" value="Stop Scrolling" onClick="window.clearInterval(s)">
</form>

</body>
</html>

In this case, when you click the button, the clearInterval() method will cancel the timer set earlier with setInterval() and the tickertape will stop moving.

Turning Up The Volume

Using a setInterval() function is identical to using a setTimeout() function in a loop. To illustrate this, consider the following example by rewriting the countdown clock example from a few pages back:

<html>
<head>
<script language="JavaScript">
var i=10;

function countDown()
{
    if(i > 0)
    {
        document.forms[0].elements[0].value=i;
        i = i-1;
    }
    else
    {
        alert("Happy New Year!");
    }
}

window.setInterval("countDown()", 1000);
</script>
</head>

<body>

<form>
<input type="text" name="counter" size="3">
</form>

</body>
</html>

In this case, I've used the setInterval() method instead of the setTimeout() method to call the countDown() function over and over again. Note the difference between the version above and the one a few pages back - above, the call to setInterval() is outside the loop, whereas earlier, the call to setTimeout() was inside the loop.

Here's one more example, this one making a <div> appear when the mouse moves over a link and automatically hiding it again after 3 seconds:

<html>
<head>
<script language="JavaScript">
function on()
{
    if(document.all)
    {
        // make <div> visible
        document.all['volume'].style.visibility='visible';
        // after 3 seconds, make it invisible
        window.setInterval("document.all['volume'].style.visibility='hidden'",3000);
    }

    if(document.layers)
    {
        // make <div> visible
        document.volume.visibility='show';
        // after 3 seconds, make it invisible
        window.setInterval("document.volume.visibility='hide'",3000);
    }

    if(!document.all && document.getElementById)
    {
        // make <div> visible
        document.getElementById("volume").style.visibility="visible";
        // after 3 seconds, make it invisible
        window.setInterval("document.getElementById('volume').style.visibility='hidden'",3000);
    }
}
</script>
</head>
<body>
<a href="#" onMouseOver="javascript:on();">Show Volume Control</a>

<div id="volume" style="color:white; font-face:Arial; background:black; position:absolute; left:550; top:200; height:150; visibility:hidden;">
Volume<br> control<br> slider<br> here
</div>

</body>
</html>

Sliding Around

Let's look at a couple more examples, which demonstrate just how useful - and varied - these functions can be. This first one uses the setInterval() method to create a timed slideshow:

<html>
<head>
<script language="JavaScript">
// slideshow image counter
var i = 0;

function slideShow()
{
    // set up list of images
    slidesArray = new Array()

    slidesArray[0]="image1.jpg"
    slidesArray[1]="image2.jpg"
    slidesArray[2]="image3.jpg"
    slidesArray[3]="image4.jpg"
    slidesArray[4]="image5.jpg"

    // load image
    document.images[0].src=slidesArray[i]

    // increment counter
    i=i+1;

    // when at the end, start again
    if(i==5) { i=0; }
}
</script>
</head>

<body onLoad="javascript:setInterval('slideShow()',5000);">
<img src="image1.jpg" name="image">
</body>

</html>

Here, the images to be displayed are stored in a JavaScript array, and a "for" loop takes care of pulling out the correct image from the array and loading it into the page. The setInterval() method is used to refresh the image with a new one every 5 seconds.

You can also use the setInterval() method to move things around on a Web page, by incrementing an X- or Y-coordinate of a page element at a predefined interval. Consider the following example, which demonstrates by moving a <div> containing an image of a car across the screen.

<html>
<head>
<script language="JavaScript">

function moveCar()
{

    if(document.all)
    {
        document.all("car").style.pixelLeft+=1;
        if(document.all("car").style.pixelLeft >= (document.body.offsetWidth-30))
            document.all("car").style.pixelLeft=-30;
    }

    if(document.layers)
    {
        parseInt(document.car.left+=5);
        if(window.innerWidth-parseInt(document.car.left)<0)
        document.car.left=-30;
    }

}

</script>
</head>

<body onLoad="javascript:setInterval('moveCar()', 1)">

<!-- layer containing car image -->
<div id="car" style="position:absolute; left:20; top:200; width: 150; height:50;">
<img src="rolls_royce.jpg" width=400 height=500 alt="" border="0">
</div>

</body>

</html>

A Long Wait

Finally, I'll wrap things up with a more practical example, one which might come in handy in your Web development. In this next example, the task is to offer the user a file upload box, which he or she can use to upload files to a Web site. Once the user selects a file for upload and initiates the transfer, a dialog box should pop up with a message asking the user to be patient. Once the file upload completes, the dialog box (window) should automatically disappear.

Now, there are a number of way to implement this. Here's how I'm going to do it:

  1. Write the code to display a form for file upload, as well as the code to accept the file and transfer it to a data directory on the server. This will be implemented in PHP.

  2. Add code to the script above to throw up a pop-up window once the upload begins.

  3. Add code to the pop-up window to keep polling the parent window for file upload status. Once the upload has finished (signified by the parent browser window loading a new URL), the pop-up window will automatically close.

First, the code for the form,

<html>
<head>
</head>
<body background="images/bkgd.gif" leftmargin="0" rightmargin="0" marginheight="0" marginwidth="0" topmargin="0">
<form action="upload.php" method="POST"  onSubmit="window.open('wait.html','resultsWindow','toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,copyhistory=no,width=500,height=400');" enctype="multipart/form-data" >

Attach File
<br>

<input name="file" type="file" size="30" maxlength="50">

<br>

<input type="submit" value="Submit">

</body>
</html>

and the server-side PHP script which processes the file submitted by the user through the form above:

<?php

// upload.php

// upload the file to the server
if ($_FILES['file'][name] != "") {
    if (is_uploaded_file($_FILES['file']['tmp_name'])) {
        // if the file is clean, move it to final location
        if (file_exists($_FILES['file']['tmp_name'])) {

            // check the size of the file
            if ($_FILES['file']['size'] < $file_limit) {
                // get the file name
                $NAME = $_FILES['file']['name'];

                // copy it to data directory
                if (copy($_FILES['file']['tmp_name'], $UPLOAD_LOCATION.$NAME)) {
                    // send browser to success page
                    header("Location: success.php");
                }
            }
        }
    }
}

?>

Once the upload is complete, the script above will redirect the browser to a success page (or an error page, if an error occurred).

Notice in the form that I'm opening a new window when the user clicks the submit button. This new window will show the "be patient" message, and must also keep checking the parent window at pre-defined intervals to see if the transfer is complete. Here's the code:

<html>
<head>
<script language="JavaScript">
<!--

// wait.html

function checkOpenerStatus() {
    var strOpener = opener.location.href;
    if(strOpener.indexOf("success.php") != -1 || strOpener.indexOf("error.php") != -1) {
        // I am going to close now
        self.close();
    }
}

// -->
</script>

</head>

<body onLoad="setInterval('checkOpenerStatus()', 1000)">

<center>
<h1>
Please wait, your upload is being processed!
<br>
This window will close automatically once the upload is complete.
</h1>
</center>

</body>
</html>

This script uses the setInterval() method to check the URL of the parent window every second and, when it detects that the parent has gone to the success or error page (indicating that the upload has completed), it automatically terminates itself with the self.close() method.

And that's about all I have time for. Over the course of this article, I introduced you to JavaScript's four timing functions, showing you how to use the setTimeout() and setInterval() methods to call a function once after a pre-defined delay, or repeatedly at a pre-defined interval. That was the easy part - and I followed it up with a bunch of examples designed to showcase some of the things you can do with this power. Among the example applications I built: a browser tickertape, a countdown clock, a timed slideshow, a variable-speed page object and a polling status window.

I hope you had fun reading this article, and that the examples sparked off some ideas of where you can use these functions in your own scripts. Till next time...see ya!

Note: Examples are illustrative only, and are not meant for a production environment. Melonfire provides no warranties or support for the source code described in this article. YMMV!

This article was first published on08 Dec 2003.