JS中setTimeout()的用法详解 た 入场券 2021-09-15 07:54 397阅读 0赞 setTimeout( ) 是属于 window 的 method, 但我们都是略去 window 这顶层物件名称, 这是用来设定一个时间, 时间到了, 就会执行一个指定的 method **1. SetTimeOut()** 1.1 SetTimeOut()语法例子 1.2 用SetTimeOut()执行Function 1.3 SetTimeOut()语法例子 1.4 设定条件使SetTimeOut()停止 1.5 计分及秒的counter **2. ClearTimeout()** **3. Set Flag ** 10.1 setTimeout( ) **setTimeout( )** 是属于 window 的 method, 但我们都是略去 window 这顶层物件名称, 这是用来设定一个时间, 时间到了, 就会执行一个指定的 method。请先看以下一个简单, 这是没有实际用途的例子, 只是用来示范 **setTimeout( )** 的语法。 1. setTimeout( ) 语法例子 **练习-69 等候三秒才执行的 alert( )** 在 第 3 章 说到 alert 对话盒, 一般是用按钮叫出来, 在这练习, 你会看到网页开启后 3 秒, 就会自动出现一个 alert 对话盒。 1. 请用浏览器开启示范磁碟中的[timeout1.htm][], 这档桉有以下内容: <html> <body bgcolor=lightcyan text=red> <h1> <font color=blue>示范网页</font> </h1> <p> </br> <p> 请等三秒! <script> setTimeout("alert('对不起, 要你久候')", 3000 ) </script> </body> </html> 2. 留意网页开启后三秒, 就会出现一个 alert 对话盒。 **setTimeout( )**是设定一个指定等候时间 (单位是千分之一秒, millisecond), 时间到了, 浏览器就会执行一个指定的 method 或 function, 有以下语法: ![2013041416352494.gif][] 今次例子是设定等 3 秒 (3000 milliseconds), 浏览器就会执行 **alert( )** 这一个method。 2. 用 setTimeout( ) 来执行 function **setTimeout( )** 通常是与 function 一起使用, 以下是一个较上个练习複杂的例子。 **练习-70 状态列中自动消失的文字** 在**练习-20**, 你看过如何用按钮在状态列显示文字, 然后再用按钮消除文字, 在这练习, 你看到如何用按钮在状态列显示文字, 而这文字会在三秒后自动消失。 1. 请用浏览器开启示范磁碟中的[timeout2.htm][], 这档桉有以下内容: <html> <body bgcolor=lightcyan text=red> <h1> <font color=blue>示范网页</font> </h1> <p> </br> <script> function clearWord(){ window.status="" } </script> <form> <input type="button" value="在状态列显示文字" onClick="window.status='Hello',setTimeout('clearWord()', 3000) "> </form> </body> </html> 2. 请在按钮上按一下,你应见到状态列出现 Hello 这字, 留意过了三秒, 这字就会消失。 1. 这处先设定一个名为 **clearWord( ) **的 function, 作以下定义: **window.status=""** 这是用来消除状态列的文字 (请看**练习-20** 的说明), 浏览器执行 **clearWord****( )** , 就会消除状态列的文字。 2. 今次按钮设定了启动以下两项工作, 用 , 分隔, 浏览器会顺序执行这两项工作: **onClick="window.status='**Hello**' , setTimeout('****clearWord****( )', ****3000****) "** 3. 今次的 **setTimeout( ) **有以下设定: ![2013041416352495.gif][] 这是设定等 3 秒 (3000 milliseconds) 浏览器就会执行 **clearWord****( ) **这一个function。 在第 2 章, 你看过如何使到父视窗开启时自动开启一个子视窗, 若观看者不关闭这子视窗, 这子视窗就会一路开启。看过以上的练习, 请你设计一个会开启子视窗的网页, 而这子视窗在开启后两秒, 就会自动关闭。 3. 不断重複执行的 setTimeout( ) **setTimeout( )** 预设只是执行一次, 但我们可以使用一个循环方式, 使到一个**setTimeout( )** 再启动自己一次, 就会使到第二个 **setTimeout( )** 执行, 第二个又启动第三个, 这样循环下去, 这 **setTimeout( ) **就会不断执行。 **练习-71 自动每秒加 1 的 function** 在这练习, 你看到如何使用 **setTimeout( ) **令文字框的数值每秒就加 1, 当然你也可以设定其他递增的速度, 例如每五秒就加 5, 或每五秒就加 1。 1. 请用浏览器开启示范磁碟中的 [timeout3.htm][], 这档桉有以下内容: <html> <head> <script> x = 0 function countSecond(){ x = x+1 document.fm.displayBox.value=x setTimeout("countSecond()", 1000) } </script> </head> <body bgcolor=lightcyan text=red><p></br> <form name=fm> <input type="text" name="displayBox"value="0" size=4 > </form> <script> countSecond() </script> </body> </html> 2. 网页开启后, 请你留意文字框中的数值转变。 3. 请你将这档桉複製去硬碟, 更改一些设定, 例如 x = x+5, 或将等候时间改为5000, 看有什麽反应。 1. 这网页有两个 script, 第一个是设定** ****countSecond****( )** 这个 function, 第二个在后的是在网页完全载入后, 就启动这 function。 2. 留意今次以下的设定: **function ****countSecond****( ) \{ ****x**** = ****x****+1 document.****fm****.****displayBox****.value = x setTimeout("****countSecond****()", ****1000****) \}** 当 **countSecond****( )** 启动后, 就会启动 **setTimeout( )**, 这个 method 在一秒后又启动 **countSecond****( )**,** countSecond( ) **启动后又启动** setTimeout( )** , 所以得出的结果是 **countSecond( ) **每秒执行一次。 3. 在 JavaScript, 我们是使用这处说的方法使到一些事项不断执行, 其中一个用途是显示转动时间, 另一个用途是设定跑动文字, 随后的章节会有例子。 用上述的方法设定时间, **setTimeout( )** 虽然设定了是一秒, 但浏览器还有另外两项功能要执行, 所以一个循环的时间是稍多于一秒, 例如一分钟可能只有58 个循环。 4. 设定条件使 setTimeout( ) 停止 **setTimeout( ) **的迴圈开始后, 就会不断重複, 在上个练习, 你看到文字框的数字不断跳动, 但我们是有方法使到数字跳到某一个数值就停下来, 其中一个方法是用** if...else **设定一个条件, 若是 TRUE 就继续执行 **setTimeout( )** , 若是 FALSE 就停止。 例如要使到上个练习的 counter 跳到 20 就停下, 可将有关的 function 作以下的更改。 **function ****countSecond****( ) \{ if ( ****x**** < **20** ) \{ ****x**** = ****x ****+ **1 ** document.****displaySec****.****displayBox****.value = ****x** ** setTimeout("****countSecond****( )", 1000) \} \}** 5. 计分及计秒的 counter 在前面的练习, 相信你已学识如何使用 **setTimeout( )**, 现在请你看一个较複习的例子。 **练习-72 计时的 counter** 在这练习, 你要设定两个文字框, 一个显示分钟, 另一个显示秒, 网页开启后, 就会在这两个文字框中自动计时。 1. 请用浏览器开启示范磁碟中的[timeout4.htm][], 这档桉有以下内容: <html> <head> <script> x=0 y=-1 function countMin( ) \{ y=y+1 document.displayMin.displayBox.value=y setTimeout("countMin( )",60000) \} **function ****countSec****( ) \{ ****x ****= ****x ****+ **1 ** z =****x ****% **60 ** document.****displaySec****.****displayBox****.value=****z** ** setTimeout("****countSec****()", **1000**) \} </script> </head>** **<body bgcolor=lightcyantext=red> <p> </br> <table> <tr valign=top> <td> **你在本网页的连线时间是:**</td> <td> <form name=****displayMin****> <input type="text" name="****displayBox****"value="**0**" size=**4** > </form> </td> <td> 分 </td> <td> <form name=****displaySec****></td> <td> <input type="text" name="****displayBox****"value="**0**" size=**4** > </form> </td> <td>** 秒。**</td> </tr> </table> <script>** **countMin****( )** **countSec****( ) </script> </body> </html>** 2. 请你留意两个文字框中的数字转变。 1. 这网页有两个 function, 一个用来计分钟, 一个用来计秒。在这处, 笔者只是示范**setTimeout( ) **的操作, 因为计时器有其他更精简的写法。**(留意: 这方式的计时并不准确。)** 2. 留意计秒的 function: **function ****countSec****( ) \{ ****x**** = ****x ****+ **1 ** z = ****x****% **60 ** document.****displaySec****.****displayBox****.value=****z** ** setTimeout("****countSec****()", **1000**)** **\}** 这处的 **%** 符号是 modulus (馀数), 例如 **z ****= ****x ****% **60 表示先进行 **x ****/ **60**,** 得出的馀数作为** z** 这变数, 例如 82 秒, modulus 就是 22, 所以文字框会显示 22 而不是 82。 3. 若你要将单位数字在前加上 0, 例如 01, 02, 03 等, 可用以下方法: **function ****countSec****( ) \{ ****x**** = ****x ****+ **1 ** z = ****x ****% **60 ** if (****z**** < **10**) \{ ****z**** = "**0**"+ ****z ****\} document.****displaySec****.****displayBox****.value=****z** ** setTimeout("****countSec****()", **1000**) \}** 10.2 clearTimeout( ) 在前一节, 你看过如何使用 **setTimeout( ) **来使到浏览器不断执行一个 function, 当一个 **setTimeout( ) **开始了循环的工作, 我们要使它停下来, 可使用 **clearTimeout( )** 这 method。 ** clearTimout( )** 有以下语法: **clearTimeout(****timeoutID****)** 要使用 **clearTimeout( )**, 我们设定 **setTimeout( )** 时, 要给予这 **setTimout( )** 一个名称, 这名称就是 **timeoutID** , 我们叫停时, 就是用这 **timeoutID**来叫停, 这是一个自订名称, 但很多程式员就以 **timeoutID** 为名。 在下面的例子, 笔者设定两个 **timeoutID**, 分别命名为 **meter1** 及 **meter2**, 如下: **timeoutID ↓** **meter1**** =setTimeout("****count1****()", **1000**)** **meter2**** =setTimeout("****count2****()", **1000**)** 使用这 **meter1** 及 **meter2** 这些 **timeoutID** 名称, 在设定 **clearTimeout( ) **时, 就可指定对哪一个** setTimeout( ) **有效, 不会扰及另一个** setTimeout( ) **的操作。 **练习-73 可停止的 setTimeout( )** 这练习以**练习-71**为蓝本, 但作了两个改变: (1) 有两个 **setTimeout( )**, (2) 有两个按钮, 分别可停止这两个 **setTimout( )**。 1. 请用浏览器开启示范磁碟中的[clear.htm][], 这档桉有以下内容: **<html> <head> <script>** **x**** = **0 y = **0** **function ****count1****( ) \{ ****x**** = ****x****+ **1 ** document.****display1****.****box1****.value= ****x** ** meter1=setTimeout("****count1****()", **1000**) \}** **function ****count2****( ) \{ ****y**** = ****y****+ **1 ** document.****display2****.****box2****.value= ****y** ** meter2=setTimeout("****count2****()", **1000**) \} </script> </head>** **<body bgcolor=lightcyantext=red> <p> </br> <form name=****display1****> <input type="text" name="****box1****"value="**0**" size=**4** > <input type=button value="**停止计时**" onClick="clearTimeout(****meter1****)" > <input type=button value="**继续计时**" onClick="****count1****() " > </form> <p> <form name=****display2****> <input type="text" name="****box2****"value="**0**" size=**4** > <input type=button value="**停止计时**" onClick="clearTimeout(****meter2****) " > <input type=button value="**继续计时**" onClick="****count2****( ) " > </form> <script>** **count1****( )** **count2****( ) </script> </body> </html>** 2. 留意网页中的两个文字框及内裡变动的数字, 每个文字框旁有两个按钮, 请你试试两个按钮的反应。 3. 请你连续按多次 \[继续计时\]的按钮, 留意数值的跳动加快了, 原因是每按一次就启动 function 一次, 每个 function 都令数值跳动, 例如启动同一的 function 四次, 就会一秒跳四次。(请看下一节) 10.3 Set flag 前个练习说到我们用一个按钮来启动一个 function, 每按一下就会启动这 function 一次, 请看以下例子。 **练习-74 效果重複的 setTimeout( )** 这练习实际是将 **练习-73** 简化, 只有一个计时器, 笔者想示范的是每按 \[继续计时\] 一次, 就会启动 **count****( )**这 function 一次。 1. 请用浏览器开启示范磁碟中的[flag1.htm][], 这档桉有以下内容: **<html> <head> <script>** **x****=**0 **function ****count****( ) \{ ****x ****= ****x ****+ **1 ** document.****display****.****box****.value= x timeoutID=setTimeout("****count****()", **1000**) \} </script> </head> <body bgcolor=lightcyantext=red> <p> </br> <form name=****display****> <input type="text" name="****box****"value="**0**" size=**4** > <input type=button value="**停止计时**" onClick="clearTimeout(****timeoutID****) " > <input type=button value="**继续计时**" onClick="****count****( ) " > </form> <p>** **<script>** **count****( ) </script> </body> </html>** 2. 网页开启后, 你应见到文字框中的数字跳动, 请你按四次 \[继续计时\], 留意这会加快数字跳动, 原因是有关的 function 被开启了多个, 每个都会使数字转变。 3. 按了四次 \[继续计时\] 的按钮后, 请你按 \[停止计时\] 的按钮, 你会发现要按五次才能停止数字跳动。 在编写程式时, 我们常要提防使用者作出一些特别动作, 例如使用者按两次 \[继续计时\] 按钮, 这计时器就失准了。我们是否有办法使到一个按钮被按一次就失效呢? 这就不会产生重複效果。 笔者藉这处的例子 (随后还有多个例子), 解说程式中一个 set flag (设定旗标) 的概念, flag 是一个记认, 一般来说, 这可以是 0 或是 1 (也可用 on 或 off, 或任何两个自选的名称或数字), 但也可以是 2、3、4 或更大的数字, 在这例子有以下设定: 1. 程式开启时** ****flag****=**0。 2. 当 **counter( ) **执行时会顺便将 **flag** 变为 1。 3. 在 \[继续计时\] 这按钮的反应中, 会先检查 **flag** 是 0 或是 1, 若是 0 就会产生作用, 若是 1 就没有反应。 4. 使用这 flag 的方式, **count****( )** 这 function 开启后, \[继续计时\] 这按钮就没有作用。 这处的 flag 是一个变数, 可任意取名, 我们用 flag来称呼这变数的原因, 是因为这变数好处一支旗, 将旗竖起 (flag is on), 就会产生一个作用, 将旗放下 (flag is off), 就产生另一个作用。 **练习-75 只可开启一次的 function** 这练习是将上个练习加多一个 flag, 使到每次只能有一个 count( ) 这 function 在进行。 1. 请用浏览器开启示范磁碟中的[flag2.htm][], 这档桉有以下内容: **<html> <head> <script>** **x**** = **0 **flag**** = **0 **function ****count****( ) \{ ****x**** = ****x****+ **1 ** document.****display****.****box****.value= ****x** ** timeoutID=setTimeout("****count****()", **1000**) flag = **1 **\}** **function ****restart****( ) \{ if (****flag****==**0**) \{ ****count****( ) \} \} </script> </head>** **<body bgcolor=lightcyantext=red> <p> </br> <form name=****display****> <input type="text" name="****box****"value="**0**" size=**4** > <input type=button value="**停止计时**" onClick="clearTimeout(****timeoutID****);****flag****=**0**" > <input type=button value="**继续计时**" onClick="****restart****() " > </form> <p>** **<script>** **count****( ) </script>** **<form> <input type=button value="**Show flag**" onClick="alert('**The flag now is '**+ ****flag****)" > </form> </body> </html>** 2. 在网页中, 你应见到三个按钮及文字框中的数字跳动。 3. 请你按 \[Show flag\]这按钮, 应见到一个话对盒显示 flag 是 1。 4. 请你按 \[停止计时\]这按钮, 数字停止跳动, 请你按 \[Show flag\] 这按钮, 应见到话对盒显示 flag 是 0。 5. 请你按多次 \[继续计时\]这按钮, 你应见到数字不会加快, 请你按 \[Show flag\]这按钮, 应见到话对盒显示 flag 变回 1。 1. 这网页第 4 行有这一句: **flag****=**0 , 这是设定 **flag** 这变数及将初始值定为 0, 你也可将初始值定为 1, 随后有关的 0 和 1 对调。 2. **count****( )** 这 function 最后一句是** ****flag****=**1 , 所以启动 **count****( )** 后, **flag** 就会变为 1。 3. \[继续计时\] 的按钮是用来启动 **restart****( )**, 这 function 有以下设定: **function restart( ) \{ if (****flag****==**0**) \{ ****count****( ) \} \}** 这处的 if statement 检查 **flag**是否等于 0, 若是 0 就启动 **count****()**, 若是 1 (即不是 0) 就没有反应,使用这方法, 若 **count****( )**已在执行中, \[继续计时\] 这按钮不会有作用。 这处的 **flag****=**1设定, 实际设为 1 或 2 或 3 等数值都是一样的,只要不是 0 就可以了, 所以这两个相对的旗标,看似是 "0" 和 "1", 实际是"0" 和 "non-zero" (非-0)。 4. \[停止计时\] 的按钮有以下设定: **onClick="clearTimeout(****timeoutID****);****flag****=**0**"** 这是停止 **setTimeout( )** 的操作时,同时将 **flag** 转回 0, 这使到**restart****( ) **这function 可以重新启动** ****count****()**。 [timeout1.htm]: http://www.takka.com.hk/jstutor/ch10/timeout1.htm [2013041416352494.gif]: /images/20210724/395c5640b9714886acb786b48e971a75.png [timeout2.htm]: http://www.takka.com.hk/jstutor/ch10/timeout2.htm [2013041416352495.gif]: /images/20210724/f4593d14f40b48f18c179e0bd7f85afb.png [timeout3.htm]: http://www.takka.com.hk/jstutor/ch10/timeout3.htm [timeout4.htm]: http://www.takka.com.hk/jstutor/ch10/timeout4.htm [clear.htm]: http://www.takka.com.hk/jstutor/ch10/clear.htm [flag1.htm]: http://www.takka.com.hk/jstutor/ch10/flag1.htm [flag2.htm]: http://www.takka.com.hk/jstutor/ch10/flag2.htm
还没有评论,来说两句吧...