纯js实现倒计时功能


Posted in Javascript onJanuary 06, 2017

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

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

Javascript 相关文章推荐
javascript xml为数据源的下拉框控件
Jul 07 Javascript
在jQuery 1.5中使用deferred对象的代码(翻译)
Mar 10 Javascript
javascript学习笔记(十) js对象 继承
Jun 19 Javascript
javascript实现div的拖动并调整大小类似qq空间个性编辑模块
Dec 12 Javascript
jQuery性能优化28条建议你值得借鉴
Feb 16 Javascript
JQuery中SetTimeOut传参问题探讨
May 10 Javascript
原生js实现半透明遮罩层效果具体代码
Jun 06 Javascript
jQuery+CSS实现的网页二级下滑菜单效果
Aug 25 Javascript
jQuery禁用快捷键例如禁用F5刷新 禁用右键菜单等的简单实现
Aug 31 Javascript
jQuery实现获取选中复选框的值实例详解
Jun 28 jQuery
javascript严格模式详解(含严格模式与非严格模式的区别)
Nov 12 Javascript
easyUI使用分页过滤器对数据进行分页操作实例分析
Jun 01 Javascript
JS正则截取两个字符串之间及字符串前后内容的方法
Jan 06 #Javascript
微信小程序开发教程-手势解锁实例
Jan 06 #Javascript
jQuery ajax的功能实现方法详解
Jan 06 #Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
Jan 06 #Javascript
Jqprint实现页面打印
Jan 06 #Javascript
JS使用正则截取两个字符串之间的字符串实现方法详解
Jan 06 #Javascript
jQuery EasyUi 验证功能实例解析
Jan 06 #Javascript
You might like
无JS,完全php面向过程数据分页实现代码
2012/08/27 PHP
php保存信息到当前Session的方法
2015/03/16 PHP
PHP遍历数组的方法汇总
2015/04/30 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
PHP文件上传之多文件上传的实现思路
2016/01/27 PHP
脚本收藏iframe
2006/07/21 Javascript
用javascript实现兼容IE7的类库 IE7_0_9.zip提供下载
2007/08/08 Javascript
Javascript 按位左移运算符使用介绍(
2014/02/04 Javascript
js语法学习之判断一个对象是否为数组
2014/05/13 Javascript
使用JQuery实现的分页插件分享
2015/11/05 Javascript
详解angularjs的数组传参方式的简单实现
2017/07/28 Javascript
详解动画插件wow.js的使用方法
2017/09/13 Javascript
利用JavaScript的%做隔行换色的实例
2017/11/25 Javascript
vue select组件的使用与禁用实现代码
2018/04/10 Javascript
react在安卓中输入框被手机键盘遮挡问题的解决方法
2018/09/03 Javascript
javascript自定义日期比较函数用法示例
2019/07/22 Javascript
详解jQuery中的prop()使用方法
2020/01/05 jQuery
[01:46]新英雄登场
2019/09/10 DOTA
MySQLdb ImportError: libmysqlclient.so.18解决方法
2014/08/21 Python
跟老齐学Python之dict()的操作方法
2014/09/24 Python
python中urllib模块用法实例详解
2014/11/19 Python
python实现协同过滤推荐算法完整代码示例
2017/12/15 Python
django最快程序开发流程详解
2019/07/19 Python
python3中关于excel追加写入格式被覆盖问题(实例代码)
2020/01/10 Python
Django xadmin安装及使用详解
2020/10/26 Python
Marks & Spencer爱尔兰:英国马莎百货
2016/04/20 全球购物
日本最大化妆品和美容产品的综合口碑网站:cosme shopping
2019/08/28 全球购物
技术总监管理岗位职责
2014/03/09 职场文书
教师中国梦演讲稿
2014/04/23 职场文书
我的画教学反思
2014/04/28 职场文书
支部组织生活会方案
2014/06/10 职场文书
2014年大学生预备党员思想汇报1000字
2014/09/13 职场文书
财政局个人总结
2015/03/04 职场文书
2015年推广普通话演讲稿
2015/03/20 职场文书
中国梦党课学习心得体会
2016/01/05 职场文书
团队拓展训练心得体会
2016/01/12 职场文书