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下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
Oct 20 Javascript
jquery获得页面元素的坐标值实现思路及代码
Apr 15 Javascript
Javascript中封装window.open解决不兼容问题
Sep 28 Javascript
实例详解jQuery表单验证插件validate
Jan 18 Javascript
AngularJS基础 ng-keyup 指令简单示例
Aug 02 Javascript
jQuery插件HighCharts实现的2D面积图效果示例【附demo源码下载】
Mar 15 Javascript
node.js中grunt和gulp的区别详解
Jul 17 Javascript
node中koa中间件机制详解
Aug 22 Javascript
微信小程序使用picker实现时间和日期选择框功能【附源码下载】
Dec 11 Javascript
JavaScript面向对象的程序设计(犯迷糊的小羊)
May 27 Javascript
只有 20 行的 JavaScript 模板引擎实例详解
May 11 Javascript
Antd表格滚动 宽度自适应 不换行的实例
Oct 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
javascript编程起步(第六课)
Feb 27 #Javascript
You might like
PHP执行速率优化技巧小结
2008/03/15 PHP
php实现将HTML页面转换成word并且保存的方法
2016/10/14 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
菜鸟学习JavaScript小实验之函数引用
2010/11/17 Javascript
使用jquery修改表单的提交地址基本思路
2014/06/04 Javascript
JavaScript数据类型详解
2015/04/01 Javascript
jquery判断复选框是否选中进行答题提示特效
2015/12/10 Javascript
jQuery实现布局高宽自适应的简单实例
2016/05/28 Javascript
JS中setTimeout和setInterval的最大延时值详解
2017/02/13 Javascript
详解Node.js项目APM监控之New Relic
2017/05/12 Javascript
jQuery实现页码跳转式动态数据分页
2017/12/31 jQuery
JavaScript累加、迭代、穷举、递归等常用算法实例小结
2018/05/08 Javascript
element-ui 的el-button组件中添加自定义颜色和图标的实现方法
2018/10/26 Javascript
微信小程序控制台提示warning:Now you can provide attr &quot;wx:key&quot; for a &quot;wx:for&quot; to improve performance解决方法
2019/02/21 Javascript
微信小程序如何引用外部js,外部样式,公共页面模板
2019/07/23 Javascript
layui实现把数据表格时间戳转换为时间格式的例子
2019/09/12 Javascript
JS实现吸顶特效
2020/01/08 Javascript
JS document内容及样式操作完整示例
2020/01/14 Javascript
利用Vue的v-for和v-bind实现列表颜色切换
2020/07/17 Javascript
javascript的hashCode函数实现代码小结
2020/08/11 Javascript
Ant-design-vue Table组件customRow属性的使用说明
2020/10/28 Javascript
Python使用pygame模块编写俄罗斯方块游戏的代码实例
2015/12/08 Python
Python实现递归遍历文件夹并删除文件
2016/04/18 Python
Python中二维列表如何获取子区域元素的组成
2017/01/19 Python
Python队列、进程间通信、线程案例
2019/10/25 Python
Python 炫技操作之合并字典的七种方法
2020/04/10 Python
Python多线程实现支付模拟请求过程解析
2020/04/21 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
详解python polyscope库的安装和例程
2020/11/13 Python
法律专业个人实习自我鉴定
2013/09/23 职场文书
承诺保证书格式
2015/02/28 职场文书
幼儿园音乐教学反思
2016/02/18 职场文书
职场新人知识:如何制定一份合理的工作计划?
2019/09/11 职场文书
JavaScript控制台的更多功能
2021/04/28 Javascript
Python使用random模块实现掷骰子游戏的示例代码
2021/04/29 Python
mongodb数据库迁移变更的解决方案
2021/09/04 MongoDB