setTimeout和setInterval的浏览器兼容性分析


Posted in Javascript onFebruary 27, 2007

无意中测试AJAXRequest浏览器兼容性的时候,发现AJAXRequest.update方法在某些情况下在IE里有问题,经过测试找到是setTimeout和setInterval的问题。
问题出现在当调用AJAXRequest.update方法时,如果带了更新间隔及更新次数,那么在IE下面就会出现问题,具体表现为带了更新间隔时是函数工作,带上更新次数时函数无法在更新指定次数后停止执行。
测试几个例子之后找到了问题所在,在IE里,setTimeout和setInterval是不支持参数传递的。
演示地址:http://www.xujiwei.cn/demo/usetimer/
在Netscape的JavaScript参考中找到setTimeout的语法如下:

setTimeout 
Evaluates an expression or calls a function once after a specified number of milliseconds elapses. 
语法 
setTimeout(expression, msec) 
setTimeout(function, msec, arg1, ..., argN) 
参数 
expression  A string containing a JavaScript expression. 
msec  A numeric value or numeric string, in millisecond units.   
function  Any function.   
arg1, ..., argN  (Optional) The arguments, if any, passed to function.  

第二种使用方法就是定义了一个定时器,在执行时function时,将把调用setTimeout时定义的参数传递给function,但在IE中,并不支持这种方式的调用,也就是在执行function的时候,函数并没有接收到这些参数。如下面的例子:
<script type="text/javascript"> 
function show(str) { 
    alert("my site: "+str); 
} 
setTimeout(show,100,"www.xujiwei.cn"); 
</script>

在Firefox和Opera里,浏览器都能正确的弹出提示框显示字符串“my site: www.xujiwei.cn”,而在IE里,显示的则是“my site: undefined”,说明函数show并没有接收到参数str,所以显示出来就是一个未定义变量。
当然,如果在函数内部使用的变量是全局变量时,就不必要考虑这些问题,如:
<script type="text/javascript"> 
function show() { 
    // url是全局变量,函数正确执行 
    alert("my site: "+url); 
} 
var url="www.xujiwei.cn"; 
setTimeout(show,100); 
</script>

这段代码在IE和Firefox里都能正常工作,显示出“my site: www.xujiwei.cn”。
在变量是全局变量的情况下,可以使用语句段的方式来调用setTimeout,即使用第一种语法:
<script type="text/javascript"> 
function show(str) { 
    // url是全局变量,函数正确执行 
    alert("my site: "+str); 
} 
var url="www.xujiwei.cn"; 
setTimeout("show(url);",100); 
</script>

因为变量url是全局变量,因此定时器执行所定义的语句段“show(url);”能正确传递参数,但是如果url不是全局变量,而是一个局部变量时,执行结果就会出错了:
<script type="text/javascript"> 
function show(str) { 
    // url是全局变量,函数正确执行 
    alert("my site: "+str); 
} 
function test() { 
    var url="www.xujiwei.cn"; 
    setTimeout("show(url);",100); 
} 
test(); 
</script>

此时就会出错了,在函数test执行时,会提示url未定义,在执行定义的语句段“show(url);”时,上下文已经脱离了函数test,而url是在函数test内部定义的,所以在执行函数test的时候,变量url已经释放了。
如果要在setTimeout里面使用局部变量,并且解决在IE里的setTimeout不支持参数传递的问题,可以使用匿名函数,即在调用setTimeout时定义一个匿名函数,在这个函数内部进行原来需要进行的操作。
<script type="text/javascript"> 
function show(str) { 
    // url是全局变量,函数正确执行 
    alert("my site: "+str); 
} 
function test() { 
    var url="www.xujiwei.cn"; 
    setTimeout(function(){show(url);},100); 
} 
test(); 
</script>

在上面的例子中,调用setTimeout时定义了一个匿名函数,它的函数体是“show(url);”,因为已经定义了函数,所以在定时器调用这个函数时,变量url还是有引用的,因些函数可以正确执行,显示出字符串“my site: www.xujiwei.cn”。
总的来说,使用setTimeout或者setInterval时需要注意以下几点:
1. 定义定时器时如果是使用的表达示,那么其中的变量应该是全局变量,或者是一个直接的值,而不能是局部变量。
2. 定义定时器时如果是定义的调用函数,那么应该只写函数名,而不能加括号,如果加了就是定义返回值了。
3. 在IE里使用定时器时不能传递参数。
4. 如果要在IE里使用定时器时传递参数,可以使用匿名函数,在函数体中调用原来该调用的函数。

如有错误还请指正。

Javascript 相关文章推荐
javascript 文档的编码问题解决
Mar 01 Javascript
JS Replace 全部替换字符的用法小结
Dec 24 Javascript
js去除输入框中所有的空格和禁止输入空格的方法
Jun 09 Javascript
解决jQuery上传插件Uploadify出现Http Error 302错误的方法
Dec 18 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
Jan 04 Javascript
Jquery跨域获得Json的简单实例
May 18 Javascript
js 连续赋值的简单实现
Jun 13 Javascript
Javascript中prototype的使用详解
Jun 18 Javascript
基于JQuery及AJAX实现名人名言随机生成器
Feb 10 Javascript
使用Bootstrap + Vue.js实现表格的动态展示、新增和删除功能
Nov 27 Javascript
微信小程序之多文件下载的简单封装示例
Jan 29 Javascript
ndm:NPM的桌面GUI应用程序
Oct 15 Javascript
javascript里的条件判断
Feb 27 #Javascript
javascript第一课
Feb 27 #Javascript
javascript编程起步(第三课)
Feb 27 #Javascript
javascript编程起步(第二课)
Feb 27 #Javascript
javascript编程起步(第五课)
Feb 27 #Javascript
javascript编程起步(第四课)
Feb 27 #Javascript
javascript编程起步(第六课)
Feb 27 #Javascript
You might like
压力如何影响浓缩咖啡品质
2021/03/03 咖啡文化
php遍历目录输出目录及其下的所有文件示例
2014/01/27 PHP
smarty实现多级分类的方法
2014/12/05 PHP
微信公众号开发客服接口实例代码
2016/10/21 PHP
php批量删除操作代码分享
2017/02/26 PHP
thinkPHP实现的省市区三级联动功能示例
2017/05/05 PHP
php语言注释,单行注释和多行注释
2018/01/21 PHP
JS教程:window.location使用方法的区别介绍
2013/10/04 Javascript
让新消息在网页标题闪烁提示的jQuery代码
2013/11/04 Javascript
javascript中的正则表达式使用指南
2015/03/01 Javascript
js带闹铃功能的倒计时代码
2016/09/29 Javascript
JavaScript基本类型值-Undefined、Null、Boolean
2017/02/23 Javascript
使用JS动态显示文本
2017/09/09 Javascript
在vue中使用vue-echarts-v3的实例代码
2018/09/13 Javascript
js限制input只能输入有效的数字(第一个不能是小数点)
2018/09/28 Javascript
JavaScript find()方法及返回数据实例
2020/04/30 Javascript
python根据出生年份简单计算生肖的方法
2015/03/27 Python
PIL包中Image模块的convert()函数的具体使用
2020/02/26 Python
Python类的绑定方法和非绑定方法实例解析
2020/03/04 Python
python 按钮点击关闭窗口的实现
2020/03/04 Python
python能否java成为主流语言吗
2020/06/22 Python
python中加背景音乐如何操作
2020/07/19 Python
用Python实现定时备份Mongodb数据并上传到FTP服务器
2021/01/27 Python
解决virtualenv -p python3 venv报错的问题
2021/02/05 Python
今天学到的CSS最新技术(与图片背景相关)
2012/12/24 HTML / CSS
毕业生护理专业个人求职信范文
2014/01/04 职场文书
中国好声音华少广告词
2014/03/17 职场文书
职员竞岗演讲稿
2014/05/14 职场文书
多媒体编辑专业毕业生求职信
2014/06/13 职场文书
目标责任书格式
2014/07/28 职场文书
乡镇党委书记第三阶段个人整改措施
2014/09/16 职场文书
关于成立领导小组的通知
2015/04/23 职场文书
2015年初一班主任工作总结
2015/05/13 职场文书
大学运动会通讯稿
2015/07/18 职场文书
安装pytorch时报sslerror错误的解决方案
2021/05/17 Python
sql查询语句之平均分、最高最低分及排序语句
2022/05/30 MySQL