让JavaScript中计时器setTimeout/setInterval的回调方法支持参数传递
2011-04-10 14:59 ·风信子· 阅读(4461) 评论(8) 编辑 收藏 举报1. 背景
在JavaScript中,我们经常要用到Timer,也就是setTimeout或者setInterval这两个方法。例如:
var t1 = setTimeout(function() { //TODO: add your logic here }, 1000);
同时,我们也经常听到有人报怨说里面的这个回调方法不支持参数传递。有时候,我们想要在里面的function里面用到外部的数据时,只能在外面定义一个变量,如下:
var i = 0; setTimeout(function() { alert(i); }, 1000);
那么,我们如果能够里面这个function支持参数传递,是不是感觉要好点呢?比如写成这样[1]:
setTimeout(function(msg) { alert(msg); //显示 Hello, world! }, 1000, 'Hello, world!');
2. 初试
笔者突发奇想地试着将上述代码放到浏览器里面执行了一下:
<!DOCTYPE HTML> <html> <head> <title>JavaScript Timer Args Test</title> </head> <body> <script type="text/javascript"> (function(){ setTimeout(function(msg) { alert(msg); //显示 Hello, world! }, 1000, 'Hello, world!'); })(); </script> </body> </html>
令人惊喜的事,这段代码在Firefox 4.0, Chrome 11, Safari 5.0里面尽然能够成功的执行,弹出了Hello, world! 在IE9 中弹出的则是undefined!
3. 兼容IE
时至此刻,要想在IE下也能使用,就只有替换掉IE内置的setTimeout/setInterval方法了。如下:
/** * @author Hyacinthus ·风信子· */ (function(){ // reset timer for IE if (navigator.appName == 'Microsoft Internet Explorer') { var _preTimeout = window.setTimeout, _preInterval = window.setInterval; window.setTimeout = function(callback, after){ var l = arguments.length; if (l > 2) { var args = []; for (var i = 2; i < l; i++) { args.push(arguments[i]); } return _preTimeout(function(){ callback.apply(this, args); }, after); //记得返回timer id } else { return _preTimeout.apply(this, arguments); } } window.setInterval = function(callback, cycle){ var l = arguments.length; if (l > 2) { var args = []; for (var i = 2; i < l; i++) { args.push(arguments[i]); } return _preInterval(function(){ callback.apply(this, args); }, cycle); } else { return _preInterval.apply(this, arguments); } } } })();
4. 结语
一些比较现代的浏览器都支持js在timer的回调函数中传入参数,只是一般不为人知而已(个人感觉这种写法以后会成为js中的标准)。
希望本文对您有帮助!
最后附上完整的HTML文件,任您把玩!》点击此处《
注:[1]. 参考自NodeJs中的setTimeout语法 setTimeout(callback, delay, [arg], [...]) http://nodejs.org/docs/v0.4.5/api/timers.html