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 21 Javascript
JavaScript高级程序设计 DOM学习笔记
Sep 10 Javascript
JQuery.Ajax之错误调试帮助信息介绍
Jul 04 Javascript
jquery form 隐藏的input 选择
Apr 29 Javascript
jQuery多条件筛选如何实现
Nov 04 Javascript
JavaScript编写一个简易购物车功能
Sep 17 Javascript
微信小程序 安全包括(框架、功能模块、账户使用)详解
Jan 16 Javascript
localStorage的黑科技-js和css缓存机制
Feb 06 Javascript
JS使用Date对象实时显示当前系统时间简单示例
Aug 23 Javascript
详解关于Vuex的action传入多个参数的问题
Feb 22 Javascript
基于Vue中使用节流Lodash throttle详解
Oct 30 Javascript
微信小程序入门之指南针
Oct 22 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
这部好评如潮的动漫 知名梗频出 但是画风劝退很多人
2020/03/08 日漫
PHP ? EasyUI DataGrid 资料取的方式介绍
2012/11/07 PHP
php curl模拟post提交数据示例
2013/12/31 PHP
PHP实现图片自动清理的方法
2015/07/08 PHP
php mysql procedure实现获取多个结果集的方法【基于thinkPHP】
2016/11/09 PHP
PHP实现的常规正则验证helper公共类完整实例
2017/04/27 PHP
PHP中localeconv()函数的用法
2019/03/26 PHP
用ASP将SQL搜索出来的内容导出为TXT的代码
2007/07/27 Javascript
javascript delete 使用示例代码
2010/03/29 Javascript
jQuery中prevUntil()方法用法实例
2015/01/08 Javascript
jquery实现submit提交表单
2015/02/03 Javascript
写给小白的JavaScript引擎指南
2015/12/04 Javascript
更靠谱的H5横竖屏检测方法(js代码)
2016/09/13 Javascript
JavaScript中如何使用cookie实现记住密码功能及cookie相关函数介绍
2016/11/10 Javascript
javascript实现动态显示颜色块的报表效果
2017/04/10 Javascript
jquery实现图片上传前本地预览
2017/04/28 jQuery
JS逻辑运算符短路操作实例分析
2018/07/09 Javascript
vue实现登录页面的验证码以及验证过程解析(面向新手)
2019/08/02 Javascript
使用React代码动态生成栅格布局的方法
2020/05/24 Javascript
Threejs实现滴滴官网首页地球动画功能
2020/07/13 Javascript
[48:39]Ti4主赛事胜者组第一天 EG vs NEWBEE 2
2014/07/19 DOTA
[02:37]2018DOTA2亚洲邀请赛赛前采访 VP.no[o]ne心中最强SOLO是谁
2018/04/04 DOTA
python使用ctypes模块调用windowsapi获取系统版本示例
2014/04/17 Python
详解MySQL数据类型int(M)中M的含义
2016/11/20 Python
Python深度优先算法生成迷宫
2018/01/22 Python
python实现微信机器人: 登录微信、消息接收、自动回复功能
2019/04/29 Python
浅析HTML5:'data-'属性的作用
2018/01/23 HTML / CSS
瑞贝卡·明可弗包包官网:Rebecca Minkoff
2016/07/21 全球购物
Capitol Lighting的1800lighting.com:住宅和商业照明
2019/04/10 全球购物
Lacoste(法国鳄鱼)加拿大官网:以标志性的POLO衫而闻名
2019/05/15 全球购物
行政部总经理岗位职责
2014/01/04 职场文书
2014年征兵标语
2014/06/20 职场文书
2015年先进个人自荐书
2015/03/24 职场文书
MySQL 视图(View)原理解析
2021/05/19 MySQL
JavaScript实现酷炫的鼠标拖尾特效
2022/02/18 Javascript
nginx搭建NFS网络文件系统
2022/04/14 Servers