setTimeout与setInterval在不同浏览器下的差异

。(新手可能认为setTimeout与setInterval是javascript函数,这是错误的。新手容易将javascript对象函数与DOM对象方法混淆。)

先来一段代码,大家猜猜在各种浏览器下的结果会是怎么样的呢?


代码如下:

function f(){
var s = 'arguments.length:'+arguments.length+'; ';
for(var i=0,n=arguments.length;i< n;i++){
s += ' ['+i+']:'+arguments[i]+'; ';
}
alert(s);
}
setTimeout(f,500,"javascript","AAA")

我这里要探讨的,不是什么时候该用哪一个,而是探讨这两个方法在各浏览器中的差异。
原先我一直没觉得这两个方法会有什么乌龙,一个偶然的机会让我得知了,现在整理一下写出来和大家分享。
因为setTimeout与setInterval的参数和用法是一样的,只是功能不同,所以,为了省事,我下面只以setTimeout为例进行说明以及举例。
setTimeout被最经常用到的形式大概是如下2种样子的:


代码如下:

iTimerID = setTimeout(strJsCode, 50) //strJsCode为一个包含js代码的字符串
iTimerID = setTimeout(objFunction, 50) //objFunction为一个函数对象

第一种调用方式是传包含js代码的字符串,这种方式的好处是简洁,但坏处是运行效率差,而且不利于语法解析,有潜在风险,更重要的是,处理比较复杂的内容比较费劲,这一点和eval的弊端是一致的。
所以,我们认为,通常应当采用第二种方式调用为好。(后面我的例子均采用第2种调用方式)

现在来揭晓开头那一段代码在各种浏览器下的结果:
IE(6,7,8)是: arguments.length:0;
Opera(6,7,8)是: arguments.length:2; [0]:javascript; [1]:AAA;
Firefox(3.0)是: arguments.length:3; [0]:javascript; [1]:AAA; [2]:-15;
竟然有这么大的差别,还真是“你唱你的曲,我哼我的调”!
Firefox(3.0)下,得出的最后一个数字是不特定的,有时候是0,有时候是一个负数,这问题后面再说。
(一)IE系列中的setTimeout
首先,我们看看微软出的DHTML参考手册中是如何说的:
setTimeout Method
Evaluates an expression after a specified number of milliseconds has elapsed.
Syntax
iTimerID = window.setTimeout(vCode, iMilliSeconds [, sLanguage])
Parameters
vCode Required. Variant that specifies the function pointer or string that indicates
the code to be executed when the specified interval has elapsed.
iMilliSeconds Required. Integer that specifies the number of milliseconds.
sLanguage Optional. String that specifies one of the following values:
JScript Language is JScript.
VBScript Language is VBScript.
JavaScript Language is JavaScript.
MSDN上关于setTimeout的说明:
http://msdn.microsoft.com/en-us/library/ms536753(VS.85).aspx
也就是说,setTimeout接收3个参数,第3个参数表示脚本语言的类型,如果你再传入更多的参数,是无意义的。
因此,在IE中,以下两种都是对的。
setTimeout('alert(1)', 50);
setTimeout('msgbox "终止、重试、忽略,您看着办吧。", vbAbortRetryIgnore + vbDefaultButton2, "告诉您"', 50, 'VBScript');
(二)Mozilla系列中的setTimeout
我们看看Mozilla官方网站上 Gecko DOM Reference 手册中是如何说的:
window.setTimeout
Summary
Executes a code snippet or a function after specified delay.
Syntax
var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
var timeoutID = window.setTimeout(code, delay);
前两个参数都一样,没差别,从第三个参数就不同了。
因为目前只有IE浏览器支持多种语言的脚本,其它浏览器只支持js脚本所以不需要传语言类型的参数。
Mozilla把传给setTimeout的第3个以及更后面的更多参数依次的传给前面的func做为参数。
Firefox, Opera, Safari, Chrome等等也都是如此。
但是注意到,Mozilla上说了他家的setTimeout有一个叫做"Lateness" argument的BUG.
"Lateness" argument
Functions invoked by setTimeout are passed an extra "lateness" argument in Mozilla,
i.e., the lateness of the timeout in milliseconds. (See bug 10637 and bug 394769.)
这就是开头那个例子中,Firefox(3.0)下有一个乌龙数字的根源。
Mozilla上关于setTimeout的说明:
https://developer.mozilla.org/en/DOM/window.setTimeout
(三)其它浏览器系列(Opera, Safari, Chrome)中的setTimeout
和Mozilla系列中的基本一样,但是没有Mozilla系列中的多一个参数的BUG.

武林外传:使用setTimeout的小技巧
(1)IE中给setTimeout中的调用函数传参数
上面的分析可知,IE是不支持在setTimeout中给被调用的函数传参数的,为了浏览器世界的和谐,我们可以把函数调用参数包裹进新的匿名函数中。示例:


代码如下:

function f(a){
alert(a);
}
// setTimeout(f,50,'hello'); //用于非IE
setTimeout(function(){f('hello')},50); //通用
var str='hello';
setTimeout(function(){f(str)},50); //通用

(2)this问题
setTimeout调用的函数被执行时的上下文是全局,而不再是调用setTimeout方法时的上下文。所以,setTimeout的第一个参数的函数被执行时其this是指向window的,如果需要保留调用setTimeout方法时的this,就需要把当时的this传进去。示例:


代码如下:

function Person(name){
this.name=name;
var f=function(){alert('My name is '+this.name)};
// setTimeout(f,50); //错误
var THIS=this;
setTimeout(function(){f.apply(THIS)},50); //正确,通用
setTimeout(function(){f.call(THIS)},50); //正确,通用
}
new Person('Jack');

要说的就这些了。
发帖子不是脑力活,其实是体力活,组织文字,写例子,排版,这些没技术含量的事情是最累人最耗时间的。

(0)

相关推荐

  • 5秒后跳转效果(setInterval/SetTimeOut)

    setInterval版 复制代码 代码如下: $(function () { setInterval(function () { var time = $("#time").text(); time = parseInt(time); time--; if (time >0) { $("#time").text(time); } else { window.location = $("#url").attr("href"

  • setTimeout和setInterval的深入理解

    大概半年前发表过一篇关于setTimeout和setInterval的文章,但是现在回去仔细一看发现其实存在很多不足以及错误.事实上,setTimeout和setInterval并没有我们字面上理解的那么简单.要真正掌握并理解这两个方法,还得从javascript的单线程机制说起. [开门见山]setTimeout和setInterval是如何工作的呢? 我们知道,js是单线程执行的.所以其实setTimeout和setInterval所谓的"异步调用"事实上是通过将代码段插入到代码的

  • Jquery中使用setInterval和setTimeout的方法

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

  • setInterval和setTimeout停止的方法

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

  • setInterval,setTimeout与jquery混用的问题

    方法1. 直接在ready中调用其他方法,会提示缺少对象的错误,应用jQuery的扩展可以解决这个问题. 复制代码 代码如下: $(document).ready(function(){ $.extend({  show:function(){   alert("ready");  }});setInterval("$.show()",3000);}); 方法2. 指定定时执行的函数时不要使用引号和括号. 复制代码 代码如下: function show(){  

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

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

  • JavaScript setTimeout和setInterval的使用方法 说明

    不同的是setInterval会每隔指定的时间段就执行一次代码,具有重复性.而setTimeout只会调用后执行一次. 下面通过函数的建立和函的自动删除来深刻理解两个函数: 1.函数的建立 setTimeOut的建立: 复制代码 代码如下: showTime(); function showTime() { var today = new Date(); alert("The time is: " + today.toString()); setTimeout("showTi

  • javascript setTimeout和setInterval 的区别

    setTimeout方法是定时程序,也就是在什么时间以后干什么.干完了就拉倒. setInterval方法则是表示间隔一定时间反复执行某操作. 如果用setTimeout实现setInerval的功能,就需要在执行的程序中再定时调用自己才行.如果要清除计数器需要 根据使用的方法不同,调用不同的清除方法: 例如: tttt=setTimeout('northsnow()',1000); clearTimeout(tttt); 或者: tttt=setInterval('northsnow()',1

  • javascript setTimeout和setInterval计时的区别详解

    setTimeout方法是定时程序,也就是在什么时间以后干什么.干完了就拉倒.setInterval方法则是表示间隔一定时间反复执行某操作.如果用setTimeout实现setInerval的功能,就需要在执行的程序中再定时调用自己才行.如果要清除计数器需要 根据使用的方法不同,调用不同的清除方法:例如:(1): 复制代码 代码如下: t=setTimeout('northsnow()',1000);clearTimeout(t);(2):t=setInterval('northsnow()',

  • JavaScript SetInterval与setTimeout使用方法详解

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

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

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

  • Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)

    Document自带的方法: 循环执行:var timeid = window.setInterval("方法名或方法","延时");window.clearInterval(timeid); 定时执行:var tmid = window.setTimeout("方法名或方法", "延时");window.clearTimeout(tmid); 举例说明: A.当要执行的方法中不需要参数时 复制代码 代码如下: <scr

随机推荐