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 相关文章推荐
JS JavaScript获取Url参数,src属性参数
Mar 09 Javascript
jQuery 自动增长的文本输入框实现代码
Apr 02 Javascript
JQUBAR1.1 jQuery 柱状图插件发布
Nov 28 Javascript
jquery indexOf使用方法
Aug 19 Javascript
非html5实现js版弹球游戏示例代码
Sep 22 Javascript
JS实现遮罩层效果的简单实例
Nov 12 Javascript
JS关闭窗口与JS关闭页面的几种方法小结
Dec 17 Javascript
Bootstrap Modal遮罩弹出层(完整版)
Nov 21 Javascript
javascript垃圾收集机制的原理分析
Dec 08 Javascript
微信小程序 登陆流程详细介绍
Jan 17 Javascript
使用jQuery实现简单的tab框实例
Aug 22 jQuery
详解vue mixins和extends的巧妙用法
Dec 20 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
php实现可运算的验证码
2015/11/10 PHP
Laravel项目中timeAgo字段语言转换的改善方法示例
2019/09/16 PHP
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
2009/02/04 Javascript
javascript 混合的构造函数和原型方式,动态原型方式
2009/12/07 Javascript
js 实现无干扰阴影效果 简单好用(附文件下载)
2009/12/27 Javascript
IE6浏览器下resize事件被执行了多次解决方法
2012/12/11 Javascript
制作jquery遮罩层效果导航菜单代码分享
2013/12/25 Javascript
JQuery EasyUI的使用
2016/02/24 Javascript
jquery 全选、全不选、反选效果的实现代码【推荐】
2016/05/05 Javascript
AngularJS入门教程之XHR和依赖注入详解
2016/08/18 Javascript
AngularJS实现根据变量改变动态加载模板的方法
2016/11/04 Javascript
Vue无限滑动周选择日期的组件的示例代码
2018/07/18 Javascript
vue移动端下拉刷新和上拉加载的实现代码
2018/09/08 Javascript
JavaScript函数式编程(Functional Programming)纯函数用法分析
2019/05/22 Javascript
javascript实现前端成语点击验证优化
2020/06/24 Javascript
python获取本地计算机名字的方法
2015/04/29 Python
Python实现二维有序数组查找的方法
2016/04/27 Python
Python sqlite3事务处理方法实例分析
2017/06/19 Python
python 高效去重复 支持GB级别大文件的示例代码
2018/11/08 Python
对sklearn的使用之数据集的拆分与训练详解(python3.6)
2018/12/14 Python
Python中的枚举类型示例介绍
2019/01/09 Python
把pandas转换int型为str型的方法
2019/01/29 Python
pycharm设置python文件模板信息过程图解
2020/03/10 Python
使用python爬取抖音app视频的实例代码
2020/12/01 Python
用python批量移动文件
2021/01/14 Python
html5 拖拽及用 js 实现拖拽功能的示例代码
2020/10/23 HTML / CSS
Crucial英睿达法国官网:内存条及SSD固态硬盘升级
2018/07/13 全球购物
linux比较文件内容的命令是什么
2013/03/04 面试题
违反学校规定检讨书
2014/01/18 职场文书
汽车机修工岗位职责
2014/03/06 职场文书
2014班子“三严三实”对照检查材料思想汇报
2014/09/18 职场文书
Python使用UDP实现720p视频传输的操作
2021/04/24 Python
Python趣味实战之手把手教你实现举牌小人生成器
2021/06/07 Python
MongoDB连接数据库并创建数据等使用方法
2021/11/27 MongoDB
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
CSS浮动引起的高度塌陷问题
2022/08/05 HTML / CSS