优雅的JavaScript-定时器详解

时间:2022-08-22 17:21:34

定时器

概念: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").onclick=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 lang="en">
    <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>