欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

纯js实现倒计时功能

程序员文章站 2023-12-04 13:07:34
通过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即可调用外部域。

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