当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 纯js实现倒计时功能

纯js实现倒计时功能

2019年03月31日  | 移动技术网IT编程  | 我要评论
通过js实现页面的倒计时功能。 思路: 传入一个秒数c,c/60可以得到分钟m, c%60可以得到显示的秒数s,同理,再将m/60可是得到小时数, m/%可以得到分钟数。

通过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即可调用外部域。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持移动技术网!

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网