setTimeout和setInterval的浏览器兼容性

无意中测试AJAXRequestexternal link浏览器兼容性的时候,发现AJAXRequest.update方法在某些情况下在IE里有问题,经过测试找到是setTimeout和setInterval的问题。

问题出现在当调用AJAXRequest.update方法时,如果带了更新间隔及更新次数,那么在IE下面就会出现问题,具体表现为带了更新间隔时是函数工作,带上更新次数时函数无法在更新指定次数后停止执行。

测试几个例子之后找到了问题所在,在IE里,setTimeout和setInterval是不支持参数传递的

演示地址:

在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的时候,函数并没有接收到这些参数。如下面的例子:

  1. <script?type=”text/javascript”>
  2. function?show(str)?{
  3. ????alert(“my?site:?”+str);
  4. }
  5. setTimeout(show,100,”www.xujiwei.cn”);
  6. </script>

在Firefox和Opera里,浏览器都能正确的弹出提示框显示字符串“my?site:?www.css88.com”,而在IE里,显示的则是“my?site:?undefined”,说明函数show并没有接收到参数str,所以显示出来就是一个未定义变量。

当然,如果在函数内部使用的变量是全局变量时,就不必要考虑这些问题,如:

  1. <script?type=”text/javascript”>
  2. function?show()?{
  3. ????//?url是全局变量,函数正确执行
  4. ????alert(“my?site:?”+url);
  5. }
  6. var?url=”www.xujiwei.cn”;
  7. setTimeout(show,100);
  8. </script>

这段代码在IE和Firefox里都能正常工作,显示出“my?site:?www.css88.com”。

在变量是全局变量的情况下,可以使用语句段的方式来调用setTimeout,即使用第一种语法:

  1. <script?type=”text/javascript”>
  2. function?show(str)?{
  3. ????//?url是全局变量,函数正确执行
  4. ????alert(“my?site:?”+str);
  5. }
  6. var?url=”www.xujiwei.cn”;
  7. setTimeout(“show(url);”,100);
  8. </script>

因为变量url是全局变量,因此定时器执行所定义的语句段“show(url);”能正确传递参数,但是如果url不是全局变量,而是一个局部变量时,执行结果就会出错了:

  1. <script?type=”text/javascript”>
  2. function?show(str)?{
  3. ????//?url是全局变量,函数正确执行
  4. ????alert(“my?site:?”+str);
  5. }
  6. function?test()?{
  7. ????var?url=”www.xujiwei.cn”;
  8. ????setTimeout(“show(url);”,100);
  9. }
  10. test();
  11. </script>

此时就会出错了,在函数test执行时,会提示url未定义,在执行定义的语句段“show(url);”时,上下文已经脱离了函数test,而url是在函数test内部定义的,所以在执行函数test的时候,变量url已经释放了。

如果要在setTimeout里面使用局部变量,并且解决在IE里的setTimeout不支持参数传递的问题,可以使用匿名函数,即在调用setTimeout时定义一个匿名函数,在这个函数内部进行原来需要进行的操作。

  1. <script?type=”text/javascript”>
  2. function?show(str)?{
  3. ????//?url是全局变量,函数正确执行
  4. ????alert(“my?site:?”+str);
  5. }
  6. function?test()?{
  7. ????var?url=”www.xujiwei.cn”;
  8. ????setTimeout(function(){show(url);},100);
  9. }
  10. test();
  11. </script>

在上面的例子中,调用setTimeout时定义了一个匿名函数,它的函数体是“show(url);”,因为已经定义了函数,所以在定时器调用这个函数时,变量url还是有引用的,因些函数可以正确执行,显示出字符串“my?site:?www.css88.com”。

总的来说,使用setTimeout或者setInterval时需要注意以下几点:

1.?定义定时器时如果是使用的表达示,那么其中的变量应该是全局变量,或者是一个直接的值,而不能是局部变量。

2.?定义定时器时如果是定义的调用函数,那么应该只写函数名,而不能加括号,如果加了就是定义返回值了。

3.?在IE里使用定时器时不能传递参数。

4.?如果要在IE里使用定时器时传递参数,可以使用匿名函数,在函数体中调用原来该调用的函数。

赞(0) 打赏
未经允许不得转载:WEBTian开发 » setTimeout和setInterval的浏览器兼容性

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Tian开发相关广告投放 更专业 更精准

联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏