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模拟select下拉框的简单示例代码
Jan 26 Javascript
深入探讨JavaScript、JQuery屏蔽网页鼠标右键菜单及禁止选择复制
Jun 10 Javascript
JavaScript必知必会(二) null 和undefined
Jun 08 Javascript
jQuery使用deferreds串行多个ajax请求
Aug 22 Javascript
微信小程序-小说阅读小程序实例(demo)
Jan 12 Javascript
微信小程序 封装http请求实例详解
Jan 16 Javascript
基于jQuery解决ios10以上版本缩放问题
Nov 03 jQuery
vue-router路由与页面间导航实例解析
Nov 07 Javascript
Layui弹出层 加载 做编辑页面的方法
Sep 16 Javascript
JS原形与原型链深入详解
May 09 Javascript
TypeScript中条件类型精读与实践记录
Oct 05 Javascript
vue生命周期钩子函数以及触发时机
Apr 26 Vue.js
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得到mssql的存储过程的输出参数功能实现
2012/11/23 PHP
php微信开发之音乐回复功能
2018/06/14 PHP
对google个性主页的拖拽效果的js的完整注释[转]
2007/04/10 Javascript
javascript 类方法定义还是有点区别
2009/04/15 Javascript
JavaScript 关键字屏蔽实现函数
2009/08/02 Javascript
javascript基础知识大集锦(一) 推荐收藏
2011/01/13 Javascript
DWZ table的原生分页浅谈
2013/03/01 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2014/09/04 Javascript
jQuery插件HighCharts实现的2D对数饼图效果示例【附demo源码下载】
2017/03/09 Javascript
JS实现简单拖拽效果
2017/06/21 Javascript
js 两数组去除重复数值的实例
2017/12/06 Javascript
发布一款npm包帮助理解npm的使用
2019/01/03 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
layui 根据后台数据动态创建下拉框并同时默认选中的实例
2019/09/02 Javascript
vue.js循环radio的实例
2019/11/07 Javascript
Vue.js中的高级面试题及答案
2020/01/13 Javascript
vue中的过滤器及其时间格式化问题
2020/04/09 Javascript
详解vue组件之间的通信
2020/08/30 Javascript
pyv8学习python和javascript变量进行交互
2013/12/04 Python
Python time模块详解(常用函数实例讲解,非常好)
2014/04/24 Python
python中pandas.DataFrame对行与列求和及添加新行与列示例
2017/03/12 Python
python实现内存监控系统
2021/03/07 Python
对Python+opencv将图片生成视频的实例详解
2019/01/08 Python
在python image 中安装中文字体的实现方法
2019/08/22 Python
python3中编码获取网页的实例方法
2020/11/16 Python
Django框架实现在线考试系统的示例代码
2020/11/30 Python
关于探究python中sys.argv时遇到的问题详解
2021/02/23 Python
分享一个H5原生form表单的checkbox特效代码
2018/02/26 HTML / CSS
什么是方法的重载
2013/06/24 面试题
财务会计专业应届毕业生求职信
2013/10/18 职场文书
自荐信范文
2013/12/10 职场文书
建筑人员岗位职责
2013/12/25 职场文书
2014社区三八妇女节活动总结
2014/03/01 职场文书
教师年度考核评语
2014/04/28 职场文书
银行柜员优质服务心得体会
2016/01/22 职场文书
Python 中的 copy()和deepcopy()
2021/11/07 Python