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 继承详解(二)
Jul 13 Javascript
jQuery动态显示和隐藏datagrid中的某一列的方法
Dec 11 Javascript
js实现一个链接打开两个链接地址的方法
May 12 Javascript
非常实用的js验证框架实现源码 附原理方法
Jun 08 Javascript
js阻止冒泡和默认事件(默认行为)详解
Oct 20 Javascript
基于Bootstrap的网页设计实例
Mar 01 Javascript
详解通过JSON数据使用VUE.JS
May 26 Javascript
js 两个日期比较相差多少天的实例
Oct 19 Javascript
Vue-cli配置打包文件本地使用的教程图解
Aug 02 Javascript
vue项目打包后提交到git上为什么没有dist这个文件的解决方法
Sep 16 Javascript
JS实现页面侧边栏效果探究
Jan 08 Javascript
几款主流好用的富文本编辑器(所见即所得常用编辑器)介绍
Mar 17 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
解决Codeigniter不能上传rar和zip压缩包问题
2014/03/07 PHP
Yii框架form表单用法实例
2014/12/04 PHP
使用PHP编写发红包程序
2015/07/22 PHP
jQuery 页面载入进度条实现代码
2009/02/08 Javascript
深入理解javascript中的立即执行函数(function(){…})()
2014/06/12 Javascript
jquery中change()用法实例分析
2015/02/06 Javascript
javascript数组克隆简单实现方法
2015/12/16 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
Bootstrap 折叠(Collapse)插件用法实例详解
2016/06/01 Javascript
jQuery简单倒计时效果完整示例
2016/09/20 Javascript
使用jQuery实现动态添加小广告
2017/07/11 jQuery
bootstrap table表格客户端分页实例
2017/08/07 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
jQuery序列化form表单数据为JSON对象的实现方法
2018/09/20 jQuery
JavaScript两种计时器的实例讲解
2019/01/31 Javascript
python基础入门学习笔记(Python环境搭建)
2016/01/13 Python
使用Python &amp; Flask 实现RESTful Web API的实例
2017/09/19 Python
使用Eclipse如何开发python脚本
2018/04/11 Python
python实现的MySQL增删改查操作实例小结
2018/12/19 Python
Python处理时间日期坐标轴过程详解
2019/06/25 Python
python列表推导式入门学习解析
2019/12/02 Python
Pycharm安装python库的方法
2020/11/24 Python
举例讲解Python装饰器
2020/12/24 Python
简单介绍CSS3中Media Query的使用
2015/07/07 HTML / CSS
美国修容界大佬创建的个人美妆品牌:Kevyn Aucoin Beauty
2018/12/12 全球购物
Java里面有没有全局变量?为什么?
2015/02/06 面试题
Prototype如何更新局部页面
2013/03/03 面试题
国际商务专业学生个人的自我评价
2013/09/28 职场文书
计算机学生的自我评价分享
2014/02/18 职场文书
2014企业领导班子四风对照检查材料思想汇报
2014/09/17 职场文书
统计学教授推荐信
2014/09/18 职场文书
法人代表证明书
2014/09/18 职场文书
授权收款委托书
2014/09/23 职场文书
公务员年度考核登记表个人总结
2015/02/12 职场文书
社区党建工作总结2015
2015/05/13 职场文书
莫言诺贝尔获奖感言(全文)
2015/07/31 职场文书