Friday, June 15, 2007

Simple setTimeout / setInterval extra arguments IE fix

One of the coolest thing of Internet Explorer is that even version 7 doesn't respect timeouts or intervals creation functions as every other browser does!

I'm talking about extra parameters, that we need to pass inside a "temporary" (not for GC) extra function to use closures and to have same result.

Here is an example:

// i need an interval that check a variable ...
// ... and this is the way we usually do that ...
var i = setInterval((function(start){
return function(){
if(new Date - start > 990) {
alert("about 1 second: ".concat(new Date - start));
clearInterval(i);
}
}
})(new Date), 20);


Well done, two functions for our browser and boring unelegant way to code.

With FireFox, Opera, Safari and other more standard browsers, we should send directly extra arguments after delay interval.

setInterval(callback, delay, param1, param2, ..., paramN);

This means at least two things:
1 - we don't need to create a function wrapper to send arguments to callback
2 - we don't need to write many bytes to send parameter that need to be wrapper arguments that need to be sent to callback

A lot of developer uses string mode to solve this problem:
setTimeout("callback()", 20);

but as You know, eval is evil and we always prefere don't use them every time we can.

In this case, we should use "stupid" string evaluation to solve an Internet Explorer unfeaure ... but do we really need to code in this way?

Nope, and this is my simple proposal:

/*@cc_on
(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
@*/

Of course, a conditional comment to call that anonymous function only with IE browser, every other will use native setTimeout or setInterval function without problems.

Please note that usage of window.setSomething, instead of direct setSomething assignment is a must, because if You remove window from left side IE will tell You that operation is not valid while if You remove window from righ side, IE simply will never do anything with those two functions.

About IE Performances?
A bit slower intervals, it's obvious, but why should we care about a browser that allow us to changes its native functionality with just a simple trick like that?

I don't know if someone has just talked about this problem and this solution but I hope this one will be useful for your next code.

Oooops, I forgot first example? Here it is ;-)
var i = setInterval(function(start){
if(new Date - start > 990) {
alert("about 1 second: ".concat(new Date - start));
clearInterval(i);
}
}, 20, new Date);

No comments:

Post a Comment