SiteExperts.com Logo Home | Community | Developer's Paradise | Jobs
User Groups | Site Tools | Site Information | Search

Inside Technique : Extending JavaScript with Function Pointers : SetInterval and Browser Compatibility

The 4.0 browser's setInterval and clearInterval methods are extensions to the existing setTimeout and clearTimout methods. The setTimeout method causes code to execute after a specified amount of time. A common use of the timout methods in the 3.0 browsers was to create code that executes over and over again after a specified interval. Doing this was not difficult. The developer just had to remember to restart the timer after each execution. For example, to create a running clock (the clock is running in your statusbar):

function runClock() {
	window.status = new Date()
	setTimeout("runClock()",1000)
}

setTimeout("runClock()",1000)

The setInterval method makes this even easier. Instead of executing the code once, it automatically repeats the timer after each call to the script. We can rewrite our clock above as follows:

function runClock() {
	window.status = new Date()
}

setInterval("runClock()",1000)

The above use of the setInterval method is supported by both the 4.0 browsers and represents its most common usage. Beyond this common usage, both 4.0 browsers diverge slightly in their support. Internet Explorer supports an additional argument that represents the scripting language for the executed code. For example, the string "runClock()" is actually a line of script. In Internet Explorer, this line of script can be in any language supported by the browser (eg., VBScript).

Netscape Navigator, on the otherhand, provides two additional features with the setInterval method. First, they not only support a line of script, but the setInterval method can take a function pointer in place of the string-defined code. In addition, Netscape supports any number of arguments to be specified after the interval amount. These arguments are passed directly to the function specified by the setInterval function.

For example, imagine you want to create a timer that counts and displays how many seconds a user in on your page. We can create this two different ways - the first way works in both of the 4.0 browsers, while the second technique uses Netscape's function pointer support:

Our first approach below works by constructing a valid line of script to be used to call the clock() method. Notice how we need to determine the start time and then build the function call.

function clock(start) {
var d = new Date()
window.status = Math.round((d.valueOf()-start)/1000)
}

var startTime = new Date().valueOf()

setInterval("clock(" + startTime + ")",1000)

This second approach (supported only by Netscape Navigator) is a much simpler way to pass arguments into the function. In this example, we use a function pointer to determine which function to be called at each interval. Each time the function is called, the date is passed as an argument to the function. The arguments specified by setInterval are evaluated the first time the method is called not at each interval so the date in this example represents the date the first call to setInterval was made.

function clock(start) {
var d = new Date()
window.status = Math.round((d-start)/1000)
}

setInterval(clock,1000, new Date())

At first glance the second approach appears to be merely a convenience. However, the second approach offers many real-world benefits. In the first solution where we construct the line of script only scalar datatypes such as numbers and strings can be passed into the function. You cannot pass references to objects. To understand, notice that we passed the value of the date object to the clock function instead of the actual date object itself.

Where this issue really exhibits itself is with animation code. When you animate an element, you really just want to pass a reference of the element to the function. Unfortunately, since you must describe the element as a string, you can't pass the object. Instead most animation scripts pass the name of the object and then look up the object on each call.

Netscape's approach that uses function pointers and optional arguments is much more effective for handling objects. Instead of finding ways to describe the object, the object can be passed directly to the function. For example, in the second example, the date object itself is being passed to the clock function.

So far you have seen the flexibility of Netscape's implementation of the setInterval method. What if we wanted to expose the same functionality in Internet Explorer? Next we show you how to override Internet Explorer's setInterval support.