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 相关文章推荐
JQuery Easyui Tree的oncheck事件实现代码
May 28 Javascript
Extjs4 类的定义和扩展实例
Jun 28 Javascript
非常好用的JsonToString 方法 简单实例
Jul 18 Javascript
浅谈Javascript如何实现匀速运动
Dec 19 Javascript
jfreechart插件将数据展示成饼状图、柱状图和折线图
Apr 13 Javascript
JavaScript学习笔记之创建对象
Mar 25 Javascript
Vue2.0 从零开始_环境搭建操作步骤
Jun 14 Javascript
为vue-router懒加载时下载js的过程中添加loading提示避免无响应问题
Apr 03 Javascript
JS实现获取word文档内容并输出显示到html页面示例
Jun 23 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
Aug 19 Javascript
移动端图片上传旋转、压缩问题的方法
Oct 16 Javascript
详解javascript void(0)
Jul 13 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
使用PHPMYADMIN操作mysql数据库添加新用户和数据库的方法
2010/04/02 PHP
解析PHP跨站刷票的实现代码
2013/06/18 PHP
PHP 开发者该知道的 5 个 Composer 小技巧
2016/02/03 PHP
Laravel5权限管理方法详解
2016/07/26 PHP
详解Yii2 rules 的验证规则
2016/12/02 PHP
php数值转换时间及时间转换数值用法示例
2017/05/18 PHP
Laravel框架验证码类用法实例分析
2019/09/11 PHP
基于SVG的web页面图形绘制API介绍及编程演示
2013/06/28 Javascript
node.js中的fs.statSync方法使用说明
2014/12/16 Javascript
详解vue2 $watch要注意的问题
2017/09/08 Javascript
推荐VSCode 上特别好用的 Vue 插件之vetur
2017/09/14 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
2017/10/14 jQuery
vue富文本框(插入文本、图片、视频)的使用及问题小结
2018/08/17 Javascript
vue父组件触发事件改变子组件的值的方法实例详解
2019/05/07 Javascript
浅谈Node新版本13.2.0正式支持ES Modules特性
2019/11/25 Javascript
javascript递归函数定义和用法示例分析
2020/07/22 Javascript
[02:42]岂曰无衣,与子同袍!DOTA2致敬每一位守护人
2020/02/17 DOTA
python逐行读取文件内容的三种方法
2014/01/20 Python
Python导出数据到Excel可读取的CSV文件的方法
2015/05/12 Python
Python第三方库xlrd/xlwt的安装与读写Excel表格
2017/01/21 Python
Python多进程multiprocessing.Pool类详解
2018/04/27 Python
Win8.1下安装Python3.6提示0x80240017错误的解决方法
2018/07/31 Python
python的slice notation的特殊用法详解
2019/12/27 Python
python圣诞树编写实例详解
2020/02/13 Python
浅谈python累加求和+奇偶数求和_break_continue
2020/02/25 Python
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
新西兰航空中国官网:Air New Zealand China
2018/07/24 全球购物
大一自我鉴定范文
2013/12/27 职场文书
家长给学校的建议书
2014/05/15 职场文书
食品安全宣传标语
2014/06/07 职场文书
2015年初中教师个人工作总结
2015/07/21 职场文书
公司劳动纪律管理制度
2015/08/04 职场文书
想要创业,那么你做好准备了吗?
2019/07/01 职场文书
[有人@你]你有一封绿色倡议书,请查收!
2019/07/18 职场文书
php 原生分页
2021/04/01 PHP
HTML5简单实现添加背景音乐的几种方法
2021/05/12 HTML / CSS