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 上下滚动广告
Jun 17 Javascript
基于JQuery的密码强度验证代码
Mar 01 Javascript
jQuery右键菜单contextMenu使用实例
Sep 28 Javascript
JavaScript和CSS交互的方法汇总
Dec 02 Javascript
Bootstrap源码解读导航条(7)
Dec 23 Javascript
原生JS实现日历组件的示例代码
Sep 22 Javascript
node作为中间服务层如何发送请求(发送请求的实现方法详解)
Jan 02 Javascript
微信小程序实现折叠面板
Jan 31 Javascript
详解Vue+Element的动态表单,动态表格(后端发送配置,前端动态生成)
Apr 20 Javascript
layui+jquery支持IE8的表格分页方法
Sep 28 jQuery
微信小程序开发之转发分享功能
Oct 22 Javascript
Vue指令实现OutClick的示例
Nov 16 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中spl_autoload_register()和__autoload()区别分析
2014/05/10 PHP
利用PHP函数计算中英文字符串长度的方法
2014/11/11 PHP
PHP实现递归复制整个文件夹的类实例
2015/08/03 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
2020/02/15 PHP
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
2010/06/18 Javascript
js数组Array sort方法使用深入分析
2013/02/21 Javascript
Javascript动态引用CSS文件的2种方法介绍
2014/06/06 Javascript
谈谈impress.js初步理解
2015/09/09 Javascript
谈谈js中的prototype及prototype属性解释和常用方法
2015/11/25 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
JS HTML5拖拽上传图片预览
2016/07/18 Javascript
用js读写cookie的简单方法(推荐)
2016/08/08 Javascript
JavaScript运动框架 解决速度正负取整问题(一)
2017/05/17 Javascript
QRCode.js:基于JQuery的生成二维码JS库的使用
2017/06/23 jQuery
基于webpack-hot-middleware热加载相关错误的解决方法
2018/02/22 Javascript
详解微信小程序开发用户授权登陆
2019/04/24 Javascript
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
微信小程序中如何使用flyio封装网络请求
2019/07/03 Javascript
在vue中动态添加class类进行显示隐藏实例
2019/11/09 Javascript
[43:47]DOTA2上海特级锦标赛主赛事日 - 4 败者组第四轮#2 MVP.Phx VS Fnatic第一局
2016/03/05 DOTA
python私有属性和方法实例分析
2015/01/15 Python
Pycharm无法显示动态图片的解决方法
2018/10/28 Python
使用pyinstaller打包PyQt4程序遇到的问题及解决方法
2019/06/24 Python
python多线程semaphore实现线程数控制的示例
2020/08/10 Python
python从Oracle读取数据生成图表
2020/10/14 Python
日本最大的购物网站乐天市场国际版:Rakuten Global Market(支持中文)
2020/02/03 全球购物
编码实现字符串转整型的函数
2012/06/02 面试题
绿化先进工作者事迹材料
2014/01/30 职场文书
抄作业检讨书
2014/02/17 职场文书
竞选学生会演讲稿
2014/04/25 职场文书
医学生求职信
2014/07/01 职场文书
教师暑期培训感言
2014/08/15 职场文书
好媳妇事迹材料
2014/12/24 职场文书
金秋助学感谢信
2015/01/21 职场文书
2015年话务员工作总结
2015/04/29 职场文书
css3 利用transform-origin 实现圆点分布在大圆上布局及旋转特效
2021/04/29 HTML / CSS