纯js实现倒计时功能

原创 2017-01-14 13:24:05 428
摘要:本文主要介绍了通过js实现页面的倒计时功能的思路与方法,具有一定的参考价值,下面跟着小编一起来看下吧通过js实现页面的倒计时功能。思路: 传入一个秒数c,c/60可以得到分钟m, c%60可以得到显示的秒数s,同理,再将m/60可是得到小时数, m/%可以得到分钟数。通过setInterval每次将总秒数-1,并将计算所得时间显示到页面上。第一版的肮脏代码如下, 可以作为反面教材思考一下<h

本文主要介绍了通过js实现页面的倒计时功能的思路与方法,具有一定的参考价值,下面跟着小编一起来看下吧

通过js实现页面的倒计时功能。

思路: 传入一个秒数c,c/60可以得到分钟m, c%60可以得到显示的秒数s,同理,再将m/60可是得到小时数, m/%可以得到分钟数。通过setInterval每次将总秒数-1,并将计算所得时间显示到页面上。

第一版的肮脏代码如下, 可以作为反面教材思考一下

<html>
  <head>
    <title>Tomato</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
      var vTimeLength = 5;
      var vHour;
      var vMinutes;
      var vSeconds;
      var vRemainingTime;
      function countDown(){
        vTimeLength = vTimeLength - 1;
        vMinutes = Math.floor(vTimeLength/60);
        vSeconds = Math.floor(vTimeLength%60);
        if (vMinutes >= 60){
          vHour = Math.floor(vMinutes/60);
          var vMinutesNew = Math.floor(vMinutes%60);
          vRemainingTime = vHour + ":" + vMinutesNew + ":" + vSeconds;
        } else {
          vRemainingTime = vMinutes + ":" + vSeconds;
        }
        document.getElementById("div_countDown").innerHTML = vRemainingTime;
        if (vTimeLength < 1) {
          alert('do sth');
        }
      }
    </script>
  </head>
  <body>
    <div id="div_countDown"></div>
    <script type="text/javascript">
      setInterval("countDown()", 1000);
    </script>
  </body>
</html>

缺陷:

 1、定义了众多的全局变量,

 2、没有复用性,

 3、setInterval容易导致队列过多, 结束事件如果是非阻塞事件, 倒计时会继续执行出现负数,

 4、不符合面向对象思想。。。

针对缺陷1的解决方案是, 定义一个函数, 将相关全局变量放到函数内部,使之成为局部变量

针对缺陷2:为函数指定参数,提高复用性。 这里定义了3个参数vTimeLength为倒计时总秒数,showTagId为显示到页面元素的id, callback为倒计时结束后的回掉方法

针对缺陷3:用setTimeout替代setInterval

优化后的代码如下:

<html>
  <head>
    <title>countdown</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
      function countDown(vTimeLength, showTagId, callback) {
        var vHour;
        var vMinutes;
        var vMinutesNew
        var vSeconds;
        var vRemainingTime;
        function countDownInner(vTimeLength){
          vMinutes = Math.floor(vTimeLength/60);
          vSeconds = Math.floor(vTimeLength%60);
          if (vMinutes >= 60){
            vHour = Math.floor(vMinutes/60);
            vMinutesNew = Math.floor(vMinutes%60);
            vRemainingTime = vHour + ":" + vMinutesNew + ":" + vSeconds;
          } else {
            vRemainingTime = vMinutes + ":" + vSeconds;
          }
          document.getElementById(showTagId).innerHTML = vRemainingTime;
          vTimeLength = vTimeLength - 1;
          if (vTimeLength > 0) {
            setTimeout(function(){countDownInner(vTimeLength);}, 1000);
          } else {
            callback();
          }
        }
        countDownInner(vTimeLength);
      }
    </script>
  </head>
  <body>
    <div id="div_countDown"></div>
    <script type="text/javascript">
      countDown(5, "div_countDown", function(){alert('do sth');});
    </script>
  </body>
</html>

这里有一点需要注意

setTimeout(function(){countDownInner(vTimeLength);}, 1000); 

第一次我将此句写成了

setTimeout(countDownInner(vTimeLength), 1000); 

结果函数直接执行了, 没有等待1秒的时间。如果没有入参, 即setTimeout("countDownInner()", 1000); 则可正常执行。

至于前面提到的不够面向对象的缺陷, 也是刚刚接触, 这里贴出代码,希望能够互相交流

<html>
  <head>
    <title>count_down</title>
    <script type="text/javascript">
    var countDown = {
      flag: true, 
      hour: 0,
      minutes: 0,
      minutesNew: 0,
      seconds: 0,
      show: 0,
      current: 0,
      length: 0,
      showTagId: null,
      // callback: null,
      countDownInner: function(vTimeLength){
        if (!this.flag) {
          return;
        }
        var that=this;
        this.current = vTimeLength;
        minutes = Math.floor(vTimeLength/60);
        seconds = Math.floor(vTimeLength%60);
        if (minutes >= 60){
          hour = Math.floor(minutes/60);
          minutesNew = Math.floor(minutes%60);
          show = hour + ":" + minutesNew + ":" + seconds;
        } else {
          show = minutes + ":" + seconds;
        }
        document.getElementById(this.showTagId).innerHTML = show;
        vTimeLength = vTimeLength - 1;
        if (vTimeLength > 0) {
          setTimeout(function(){that.countDownInner(vTimeLength);}, 1000);
        } else {
          setTimeout(function(){that.callback();}, 1000);
        }
      },
      run: function(vTimeLength, showTagId, callback) {
        if (!this.flag) {
          this.flag = true;
          this.countDownInner(this.current);
        } else if (showTagId) {
          this.length = vTimeLength;
          this.showTagId = showTagId;
          this.callback = callback;
          this.countDownInner(vTimeLength);  
        }
      },
      stop: function(){
        this.flag = false;
      }, 
      restart: function(){
        this.flag = true;
        this.countDownInner(this.length);
      }
    };
    function countDownStart() {
      countDown.run();
    }
    function countDownStop() {
      countDown.stop();
    }
    </script>
  </head>
  <body>
    <div id="div_countDown"></div>
    <script type="text/javascript">
      countDown.run(5, 'div_countDown',function(){alert('12')});
    </script>
    <span>
      <button onclick="countDownStart();">start</button>
      <button onclick="countDownStop();">stop</button>
    </span>
  </body>
</html>

一个难点是this的使用, 在函数内部, this是调用当前函数范围,所以setTimeout(function(){this.countDownInner(vTimeLength);}, 1000);会出现undefined。

解决方案是定义一个that变量接收外部函数的this指针,然后通过that即可调用外部域。

 更多关于纯js实现倒计时功能请关注PHP中文网(www.php.cn)其他文章!

发布手记

热门词条