天天看點

優雅的JavaScript-定時器詳解

定時器

概念:JavaScript提供setTimeout()函數和setInterval()函數,作為定時器,可以定時執行某個函數或者某段代碼
​
setInterval():
    按照指定的周期(以毫秒值計算)來調用函數或者計算表達式,方法會不停地調用函數,直到clearInterval()被調用或視窗關閉。
setTimeout():在指定的毫秒數後調用函數或表達式      

setTimeout

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <title>延遲執行</title>
    <style type="text/css">
​
    </style>
</head>
<body>
<input type="button" value="延遲執行" id="my_btn"/>
​
</body>
<script type="text/javascript">
//setTimeout的使用
    console.log(1);
    setTimeout("console.log(2)",1000);
    console.log(3);
​
//延時執行的是函數
    function fn() {
        console.log(4);
    }
setTimeout(fn,1000);
​
//也可以是匿名函數(常用)
    setTimeout(function () {
        console.log(5)
    },1000);
​
​
    //匿名函數帶參數(Ie9以下不支援)
    setTimeout(function (a,b) {
        console.log(a+b);
    },1000,4,5);
​
​
function sumfn(a,b) {
    console.log(a+b);
}
​
setTimeout(function () {
    sumfn(5,6)
},1000);
​
注意:
       如果setTimeout延遲運作的是一個對象中的某個方法,
       那麼方法内部的this指針指向的是全局環境,而不是目前的對象
​
var name="全局";
var obj={
    name:"對象的",
    sayHello:function () {
        console.log(this.name)
    }
}
obj.sayHello();
​
//延遲執行函數的是某個對象的方法
    setTimeout(obj.sayHello,1000);
​
//解決以上this指針的問題
    setTimeout(function () {
        obj.sayHello();
    },1000);
​
    document.getElementById("my_btn").οnclick=function () {
        setTimeout(function () {
            alert(this.value);
        },1000);
    }
​
​
</script>
</html>
​
​
總結:
   setTimeout()函數,用來指定某個函數或者某段代碼在多長毫秒值之後執行,它有一個傳回值,這個傳回值表示這個定時器的編号。
   我們可以利用這個編号,做銷毀功能
   文法:
      setTimeout(fn|code,delay);
      參數:
         fn:表示多少毫秒之後執行的函數
         code:表示多少毫秒之後執行的代碼(如果寫的是代碼那麼用“|”給括起來,其實是JavaScript裡使用eval()函數來把字元串轉成代碼)
         delay:表示延時執行的時間(機關:毫秒)
               

setInterval

setInterval()函數用法和setTimeout()函數一樣
唯一的差別:
   循環執行某個函數或者代碼塊,每個一段時間執行一次


案例:秒表

<!doctype html>
<html >
    <head>
        <meta charset="UTF-8">
        <title>ipone秒表</title>
        <style type="text/css">
            #out_div{
                width: 350px;
                height: 500px;
                margin: 0 auto;
                background: #ccc;
            }
    
            #top_div {
                width: 350px;
                height: 200px;
                background: red;

            }

            #center_div{
                width: 350px;
                height: 100px;
                background: green;
            }

            #bottom_div {
                width: 350px;
                height: 200px;
                background: orange;
            }
            h3{
                text-align: center;
                line-height: 40px;
            }

            #small_span {
                display: block;
                height: 50px;
                text-align: right;
                font-size: 35px;
                margin-right: 20px;
            }

            #big_span {
                display: block;
                height: 50px;
                text-align: right;
                font-size: 60px;
                margin-right: 20px;
            }

            #left_btn {
                width: 50px;
                height: 50px;
                margin-top: 15px;
                margin-left: 125px;
                font-size: 20px;
            }

            #right_btn {
                width: 50px;
                height: 50px;
                margin-top: 15px;
                font-size: 20px;
            }



        </style>
    </head>
    <body>
        <div id="out_div">
            <div id="top_div">
                <h3>秒表</h3>
                <hr />
                
                <span id="small_span">00:00.00</span>
                <span id="big_span">00:00.00</span>
                

            </div>

            <div id="center_div">
                <input type="button" value="計次" 
                id="left_btn" disabled />
                <input type="button" value="啟動" 
                id="right_btn"/>
            </div>

            <div id="bottom_div">
                
            </div>
        </div>


        <script type="text/javascript">

            //秒表的實作
            var timerfn = (function () {
                //定時器的傳回值
                var timerId;

                //擷取兩個時間文本
                var smallSpan = $("small_span");
                var bigSpan = $("big_span");

                var smallM = 0; //分
                var smallS = 0; //秒
                var smallMS = 0; //毫秒
                var smallMMSS = 0; //微秒

                var bigM = 0; //分 (大)
                var bigS = 0; //秒
                var bigMS = 0; //毫秒
                var bigMMSS = 0; //微秒


                return function (flag, type) {
                    if (!flag) {
                        if (type == '複位') {
                            //清空small的文本為0
                            smallMMSS = 0;
                            smallMS = 0;
                            smallS = 0;
                            smallM = 0;

                            //清空big的文本為0
                            bigMMSS = 0;
                            bigMS = 0;
                            bigS = 0;
                            bigM = 0;

                            //文本也清空
                            smallSpan.innerHTML = "00:00.00";
                            bigSpan.innerHTML = "00:00.00";
                        }

                        clearInterval(timerId);
                        return;
                    }

                    //如果目前type是計次
                    if (type == '計次') {
                        //清空small的文本為0
                        smallMMSS = 0;
                        smallMS = 0;
                        smallS = 0;
                        smallM = 0;

                        //初不初始化都行。
                        // smallSpan.innerHTML = "00:00.00";
                    }

                    timerId = setInterval(function () {
                        //小的時間遞增
                        smallMMSS++;
                        if (smallMMSS == 10) {
                            smallMMSS = 0;
                            smallMS++;
                            if (smallMS == 10) {
                                smallMS = 0;
                                smallS++;
                                if (smallS == 60) {
                                    smallS = 0;
                                    smallM++;
                                    //..
                                }
                            }
                        }

                        //大的時間遞增
                        bigMMSS++;
                        if (bigMMSS == 10) {
                            bigMMSS = 0;
                            bigMS++;
                            if (bigMS == 10) {
                                bigMS = 0;
                                bigS++;
                                if (bigS == 60) {
                                    bigS = 0;
                                    bigM++;
                                    //..
                                }
                            }
                        }

                        //指派
                        smallSpan.innerHTML = smallM + ":" + 
                        smallS + "." + smallMS + smallMMSS;
                        bigSpan.innerHTML = bigM + ":" + 
                        bigS + "." + bigMS + bigMMSS;

                    }, 10);
                }
            })();



            //右邊按鈕的事件
            $("right_btn").onclick = function () {
                if (this.value == '啟動') {
                    this.value = '停止';
                    //左邊按鈕變計次
                    $("left_btn").value = '計次';
                    //左邊按鈕解禁
                    $("left_btn").disabled = null;

                    timerfn(true);
                } else {
                    this.value = '啟動';
                    //左邊按鈕變成複位
                    $("left_btn").value = '複位';
                    timerfn(false);
                }
            }

            //左邊按鈕事件
            $("left_btn").onclick = function () {
                if (this.value == '計次') {
                    //先清空,在啟動
                    timerfn(false, this.value);
                    timerfn(true, this.value);
                } else {

                    //清掉所有資料,并且暫停
                    timerfn(false, this.value);

                    this.value = '計次';
                    //還要變成禁用的
                    this.disabled = "disabled";
                }

            }

            //封裝通過ID獲得元素的函數
            function $ (idName) {
                return document.getElementById(idName);
            }


        </script>

    </body>
</html>



      

繼續閱讀