W tym poście opiszę jak rozwiązać problem z przekazywaniem argumentów w funkcji setTimeout w przeglądarce Internet Explorer, który pojawił się w trakcie mojej pracy nad kodem JavaScript.
Problem polega na tym, że przeglądarka IE nie przekazuje argumentów do funkcji, gdy funkcja jest wywoływana z opóźnieniem (setTimeout) lub w interwałach czasowych (setInterval).
// przydatne funkcje
Array.prototype.clone = function(){
return this.slice(0);
};
Object.prototype.toArray = function(){
var arr = [];
for( var i in this ){
if( this.hasOwnProperty(i) ){
arr.push(this[i]);
}
}
return arr;
};
var argToArray = function(arg){
var arr = [];
for( var i = 0; i < arg.length; ++i ){
if( arg.hasOwnProperty(i) ){
arr.push(arg[i]);
}
}
return arr;
};
// safeTimeout - odpowiednik funkcji setTimeout wykorzystujacy ta funkcje
// oraz dzialajacy prawidlowo rowniez w IE
var safeTimeout = function(fn, t){
if( typeof(fn) == typeof(function(){}) ){
var arg = argToArray(arguments).slice(2);
return setTimeout(function(){
fn.apply(this, arg);
}, t);
}
return setTimeout(fn, t);
};
// safeInterval - odpowiednik funkcji setInterval
var safeInterval = function(fn, t){
if( typeof(fn) == typeof(function(){}) ){
var arg = argToArray(arguments).slice(2);
return setInterval(function(){
fn.apply(this, arg);
}, t);
}
return setInterval(fn, t);
};
// funkcja testowa sprawdzajaca poprawnosc powyzszych funkcji
var testFunction = function(a, b){
alert('1. ' + a + '\n2. ' + b);
};
// uruchomienie setTimeout w IE nie da oczekiwanego rezultatu (screen powyzej)
// parametry nie sa przekazywane do wywolywanej funkcji
setTimeout(testFunction, 1, 'pierwszy argument', 'drugi argument');
// wywolanie funkcji naprawiajacej ten problem przynosi oczekiwany rezultat
safeTimeout(testFunction, 1, 'pierwszy argument', 'drugi argument');
// test funkcji dla pierwszego parametru bedacego String`iem
safeTimeout('alert(\'evaluation test\')', 1);
// uruchomienie funkcji czyszczacej interwal czasowy z opoznieniem 5 sekund
safeTimeout(function(iid){
clearInterval(iid);
},
5e3,
// uruchomienie funcki testowej w interwalach co 1 sekunde
safeInterval(testFunction, 1e3, 'pierwszy argument', 'drugi argument')
);