JavaScript的window.setTimeout()方法

来源:互联网 发布:逆战数据怎么开启 编辑:程序博客网 时间:2024/05/16 19:30

JavaScript的window.setTimeout()方法


一、window.setTimeout()方法
       先看看window.setTimeout函数的定义:Gecko DOM Reference-DOM window Reference-window.setTimeout。
其中,给出该函数的用法:


var timeoutID = window.setTimeout(func, delay, [param1, param2, ...]);
var timeoutID = window.setTimeout(code, delay);



使用说明:
引用
*  timeoutID is the ID of the timeout, which can be used later with window.clearTimeout.
* func is the function you want to execute after delay milliseconds.
* code in the alternate syntax, is a string of code you want to execute after delay milliseconds. (Using this syntax is not recommended for the same reasons as using eval())
* delay is the number of milliseconds (thousandths of a second) that the function call should be delayed by. Note that the actual delay may be longer, see Notes below.
Note that passing additional parameters to the function in the first syntax does not work in Internet Explorer.


       正如红色标记的文字说明,code和param1、param2等参数,因考虑到兼容性问题,一般不建议使用。delay 的单位是毫秒(ms)。所以,最后的用法可简化为:


var timeoutID = window.setTimeout(func, delay);


格式很简单,注意事项可就多了。
※ 为什么写成window.setTimeout()方法?
       因为需要明确,setTimeout函数是window对象的方法,平时写setTimeout()只是简写。由于面向的是window对象,所以后面不少的问题都与该前提有关,继续往下阅读时,请务必留意。


二、基本使用
1、简单用法
       在HTML代码<div id="box"></div>后面加入:(因为输出信息需加到该div中,故必须在其后面运行脚本)


<script type="text/javascript">
  printNow();
  clearTimeout(timeout);
  timeout=setTimeout(printNow,1000); //留意printNow的写法
</script>



输出结果:
引用
Now is: 2010-6-11 23:8:25 78
Now is: 2010-6-11 23:8:26 78


       简单吧?继续看下面的。


2、参数func 的写法
       不知道您有没有留意,在上面setTimeout函数后面,延迟执行的函数,只有一个函数名(表示指向该函数的指针)。我们可以把setTimeout函数中,func参数理解为“指向延迟执行的函数的指针”。
       下面的写法也可以:


timeout=setTimeout("printNow()",1000);
timeout=setTimeout('printNow()',1000);



       但是下面的写法是错误的:


timeout=setTimeout('printNow',1000); //不会报错,但实际没有执行
timeout=setTimeout(printNow(),1000); //不会延迟,马上执行


       第二句若用于图片加载函数,会报“内存不足”的错误。见这里。


3、带参数的func
       如果延迟执行的函数需要传递参数,那该如何写呢?
       首先,下面的写法肯定是错误的:


timeout=setTimeout(printNow(10),1000); //同样不会延迟,马上执行


       此外,正如开头提到的,setTimeout()方法是面向window对象的,全称是window.setTimeout()。所以,一般情况下,在func中传递的参数,必须是window对象的变量(即全局变量)。
例如:


<script type="text/javascript">
  printNow();
  var tips='After setTimeOut:<br />';
  clearTimeout(timeout);
  timeout=setTimeout("printNow(tips)",1000);
</script>



       这里的,tips就是window对象的变量,你可以用alert(window.tips);语句验证一下。上面的输出结果为:
引用
Now is: 2010-6-11 23:13:26 593
After setTimeOut:
Now is: 2010-6-11 23:13:27 593


       代码执行很正常。


       不过,如果给func传递的不是window对象的变量,那么又会如何呢?
       我们把上面执行的代码放到一个函数中,让tips 在函数中定义:


<script type="text/javascript">
function run() {
  printNow();
  var tips='After setTimeOut:<br />';
  clearTimeout(timeout);
  timeout=setTimeout("printNow(tips)",1000);
}
run();
</script>



       执行一下。浏览器会报'tips'未定义,因为,这时tips已经不再是window对象的变量了。这样的情况很常见,解决办法就是,利用JavaScript的特性:匿名函数。
       代码改为:


function run() {
  printNow();
  var tips='After setTimeOut:<br />';
  clearTimeout(timeout);
  timeout=setTimeout(function() {
    printNow(tips);
  },1000);
}
run();


或者:


window.setTimeout(function(){

printNow(tips);

},1000);

替换掉timeout=setTimeout(...)的部分。


再执行,可输出正常结果:
引用
Now is: 2010-6-11 23:23:49 402
After setTimeOut:
Now is: 2010-6-11 23:23:50 424


※ 无论在func中是否有参数需要传递,使用匿名函数的方式都可以使用,并且可读性更强


三、注意事项
1、执行顺序
       当初,在使用setTimeout()方法时,我一直想当然的认为其是类似其他语言中的sleep功能,但实际情况并不是这样的。
举例来说,我们把上面的代码改为:


function run() {
  printNow();
  var tips='After setTimeOut:<br />';
  clearTimeout(timeout);
  timeout=setTimeout(function() {
    var returnValue = printNow(tips);
  },1000);
  document.write(returnValue);
}
run();



       运行时,会报“returnValue is not defined”。
       为什么会这样呢?因为setTimeout()方法与sleep是不同的。
       如PHP中的sleep,在执行到该语句时,程序会睡眠,不再往下运行,当达到设定的时间后,才继续往下执行;而setTimeout()并不如此,当程序遇到setTimeout()语句时,会启动另一子进程计算等待时间,但程序并不会中断在该的位置,而会继续往下执行。当子程序到达设定时间时,会运行setTimeout()中指定的func 函数。所以,在上面的程序中,因为returnValue是由setTimeout()中的printNow函数返回才能赋值的,但因程序没有等待,故其值为空。我们把returnValue的输出改一下:


document.write(typeof(returnValue));


开始的结果为:
引用
Now is: 2010-6-12 0:7:47 328
undefined


最终是:
引用
Now is: 2010-6-12 0:7:47 328
After setTimeOut:
Now is: 2010-6-12 0:7:48 328
undefined


明白了这一点,当我们使用setTimeout()方法时,就必须考虑:不要依赖其执行func 函数的返回值来使用,而应把setTimeout()的func 函数作为最后一步的动作来处理,把需执行的操作都放到func 函数中。


2、setTimeout()面向的对象
前面已经多次提到了,setTimeout()是面向window对象的,在Gecko DOM Reference的介绍中,有如下一段话:
引用
The 'this' problem
Code executed by setTimeout() is run in a separate execution context to the function from which it was called. As a consequence, the this keyword for the called function will be set to the window (or global) object, it will not be the same as the this value for the function that called setTimeout. This issue is explained in more detail in the JavaScript reference.


也就是说,在执行setTimeout()时,this关键字面向的也是window对象。
这在JavaScript的原型对象中使用setTimeout()时特别重要,例如:


var box = document.getElementById('box');
function myClass(){
  this.num=0;
}
myClass.prototype.count=function(){
  this.num++;
  var boxContent = box.innerHTML;
  box.innerHTML = boxContent+this.num;
  if(this.num>10){return;}
  var self=this; //先把当前的this指向对象(window对象)保留下来
  setTimeout(function() {self.count();},1000);
}
var myObj=new myClass();
myObj.count();



结果为:
引用
1234567891011


       下面的几种写法都是错误的:


setTimeout("this.count()",1000);
setTimeout("count()",1000);
setTimeout(count,1000);



       它们都没有合适的使用this所指向的window对象。


3、关于clearTimeout()方法
       该方法主要用于取消setTimeout()方法的执行。当setTimeout()启动后,会返回一个timeoutID。当运行clearTimeout()方法就可以清空该值,并终止setTimeout()的执行。
       除了可用于停止外,为了避免多次执行setTimeout()方法,导致延迟时间重叠等问题,建议在每次执行该方法前,都先用clearTimeout()清掉timeoutID。


※ 以上关于setTimeout()方法的说明,同样适用于window.setInterval()方法。
其区别在于:
引用
       window.setTimeout()
       在执行时,它从载入后延迟指定的时间去执行一个表达式或者是函数,仅执行一次;与window.clearTimeout()方法一起使用。
       window.setInterval()
       在执行时,它从载入页面后每隔指定的时间执行一个表达式或者是函数(功能类似于递归函数),重复执行;和与window.clearInterval()方法一起使用。




四、参考资料
MDC window.setTimeout
精解 window.setTimeout()使用方式与参数传递问题!
setTimeout() 在js类中的使用方法
setTimeout和setInterval的使用
为什么只是load,10个图,就会出现“内存不够”的错误?



转载自:http://www.360doc.com/content/12/1021/22/7851074_242860161.shtml

原创粉丝点击