setTimeout和setInterval的浏览器兼容性分析

无意中测试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里使用定时器时传递参数,可以使用匿名函数,在函数体中调用原来该调用的函数。

如有错误还请指正。

(0)

相关推荐

  • 关于setInterval、setTimeout在jQuery中的使用注意事项

    以前写定时器的时候,总是习惯直接 setInterval("fn()",2000); 最近碰到个问题,在使用jquery写定时器时,总是会出现fn不存在的错误提示,如下 $(function(){setInterval("fn()",2000);}) 解决方法是去掉引号和括号,采用最原始的方法 $(function(){setInterval(fn,2000);}) 另外一种就是在书写jq的扩展,如下 复制代码 代码如下: $(function(){ $.exten

  • setTimeout和setInterval的区别你真的了解吗?

    甚至可能会错误的把两个实现定时调用的函数理解成了类似thread一样的东西, 认为会在一个时间片内, 并发的执行调用的函数, 似乎很好很强大, 但其实并不是如此, 实际的情况是javascript都是以单线程的方式运行于浏览器的javascript引擎中的, setTimeout和setInterval的作用只是把你要执行的代码在你设定的一个时间点插入js引擎维护的一个代码队列中, 插入代码队列并不意味着你的代码就会立马执行的,理解这一点很重要. 而且setTimeout和setInterval

  • JS中setInterval、setTimeout不能传递带参数的函数的解决方案

    在JS中无论是setTimeout还是setInterval,在使用函数名作为调用句柄时都不能带参数,而在许多场合必须要带参数, 这就需要想方法解决. 一.采用字符串形式:--(缺陷)参数不能被周期性改变 setInterval("foo(id)",1000); 二.匿名函数包装 (推荐) 复制代码 代码如下: window.setInterval(function() { foo (id); }, 1000); 这样就可以周期性执行foo(id)这个函数,而且把变量id传递进去: 三

  • setInterval和setTimeout停止的方法

    先来了解 setInterval : 1,HTML DOM setInterval() 方法 定义和用法 setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭.由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数. 语法 setInterval(code,millisec[,"lang"]) 参数 描述

  • 定时器(setTimeout/setInterval)调用带参函数失效解决方法

    首先来看下定时器的用法 1. setInterval(code,millisec[,"lang"]) setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式. 参数 描述 code 必需,要调用的函数或要执行的代码串. millisec 必需,周期性执行或调用 code 之间的时间间隔,以毫秒计.2.setTimeout(code,millisec) setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. 参数 描述 code 必需,要调用

  • Javascript对象中关于setTimeout和setInterval的this介绍

    在Javascript里,setTimeout和setInterval接收第一个参数是一个字符串或者一个函数,当在一个对象里面用setTimeout延时调用该对象的方法时 复制代码 代码如下: function obj() { this.fn = function() { alert("ok"); console.log(this); setTimeout(this.fn, 1000);//直接使用this引用当前对象 } } var o = new obj(); o.fn(); 然后

  • JavaScript SetInterval与setTimeout使用方法详解

    setTimeout和setInterval的语法相同.它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码.不过这两个函数还是有区别的,setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码.区别:window.setTimeout("function",time)://设置一个超时对象,只执行一次,无周期 window.setInterva

  • JS中setTimeout和setInterval的最大延时值详解

    前言 JavaScript提供定时执行代码的功能,叫做定时器(timer),主要由setTimeout()和setInterval()这两个函数来完成.而这篇文中主要给大家介绍的是关于JS中setTimeout和setInterval最大延时值的相关问题,需要的朋友们下面来一起学习学习吧. 先来看这样一段代码: function update() { loadData().then(function(data) { $('#content').html(data.content); var de

  • Js中setTimeout()和setInterval() 何时被调用执行的用法

    定义setTimeout()和setInterval()经常被用来处理延时和定时任务.setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式,而setInterval()则可以在每隔指定的毫秒数循环调用函数或表达式,直到clearInterval把它清除.从定义上我们可以看到两个函数十分类似,只不过前者执行一次,而后者可以执行多次,两个函数的参数也相同,第一个参数是要执行的code或句柄,第二个是延迟的毫秒数.很简单的定义,使用起来也很简单,但有时候我们的代码并不是按照我们的想象

  • Jquery中使用setInterval和setTimeout的方法

    方法1. 应用jQuery的扩展可以解决这个问题. 复制代码 代码如下: $(document).ready(function(){$.extend({  show:function(){   alert("ready");  }});setInterval("show()",3000);}); 方法2. 指定定时执行的函数时不要使用引号和括号. 复制代码 代码如下: $(function(){function show(){   alert("ready

随机推荐