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 相关文章推荐
Google排名中的10个最著名的 JavaScript库
Apr 27 Javascript
一个关于javascript匿名函数的问题分析
Mar 30 Javascript
用JavaScript修改CSS属性的代码
May 06 Javascript
php跨域调用json的例子
Nov 13 Javascript
javascript修改表格背景色实例代码分享
Dec 10 Javascript
巧用replace将文字表情替换为图片
Apr 17 Javascript
排序算法的javascript实现与讲解(99js手记)
Sep 28 Javascript
JavaScript表单验证开发
Nov 23 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
Feb 13 Javascript
微信小程序 request接口的封装实例代码
Apr 26 Javascript
Vue实现点击箭头上下移动效果
Jun 11 Javascript
jQuery class属性操作addClass()与removeClass()、hasClass()、toggleClass()
Mar 31 jQuery
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使用者状态管理功能的应用
2006/10/09 PHP
PHP中的array数组类型分析说明
2010/07/27 PHP
ThinkPHP Where 条件中常用表达式示例(详解)
2017/03/31 PHP
jquery ajax abort()的使用方法
2010/10/28 Javascript
jquery中prop()方法和attr()方法的区别浅析
2013/09/06 Javascript
异步动态加载js与css文件的js代码
2013/09/15 Javascript
ExtJS[Desktop]实现图标换行示例代码
2013/11/17 Javascript
JavaScript function 的 length 属性使用介绍
2014/09/15 Javascript
分享9点个人认为比较重要的javascript 编程技巧
2015/04/27 Javascript
微信小程序 action-sheet 反馈上拉菜单简单实例
2017/05/11 Javascript
Nodejs中使用captchapng模块生成图片验证码
2017/05/18 NodeJs
jquery获取元素到屏幕四周可视距离的方法
2018/09/05 jQuery
微信小程序生成海报分享朋友圈的实现方法
2019/05/06 Javascript
JS实现基本的网页计算器功能示例
2020/01/16 Javascript
vue组件入门知识全梳理
2020/09/21 Javascript
[00:03]DOTA2新版本PA至宝展示
2014/11/19 DOTA
python实现从网络下载文件并获得文件大小及类型的方法
2015/04/28 Python
在Python中使用成员运算符的示例
2015/05/13 Python
Python多线程中阻塞(join)与锁(Lock)使用误区解析
2018/04/27 Python
使用python获取电脑的磁盘信息方法
2018/11/01 Python
python针对mysql数据库的连接、查询、更新、删除操作示例
2019/09/11 Python
基于梯度爆炸的解决方法:clip gradient
2020/02/04 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
解决pytorch 保存模型遇到的问题
2021/03/03 Python
日本最新流行服饰网购:Nissen
2016/07/24 全球购物
给护士表扬信
2014/01/19 职场文书
社区七一党员活动方案
2014/01/25 职场文书
毕业生简历自我评价范文
2014/04/09 职场文书
《分一分》教学反思
2014/04/13 职场文书
知识就是力量演讲稿
2014/09/13 职场文书
个人买房协议书范本
2014/10/06 职场文书
魂断蓝桥观后感
2015/06/10 职场文书
导游词之青岛太清宫
2019/12/13 职场文书
用Python的绘图库(matplotlib)绘制小波能量谱
2021/04/17 Python
springboot中rabbitmq实现消息可靠性机制详解
2021/09/25 Java/Android
ant design charts 获取后端接口数据展示
2022/05/25 Javascript