前面的话

  本文属于定时器的应用部分,分别用于实现与时间相关的四个应用,包括时钟、倒计时、秒表和闹钟。与时间相关需要用到时间和日期对象Date,详细情况移步至此

时钟

  最简单的时钟制作办法是通过正则表达式的exec()方法,将时间对象的字符串中的时间部分截取出来,使用定时器刷新即可

<div id="myDiv"></div>
<script>
myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];
setInterval(function(){myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];
},500);
</script>

倒计时

【1】简易倒计时

  简易倒计时就是每1s通过setInterval将设置的时间减去1来达到要求

<div id="myDiv"><label for="set"><input type="number" id="set" step="1" value="0">秒</label><button id="btn">确定</button><button id="reset">重置</button>
</div>
<script>
var timer;
reset.onclick = function(){history.go();
}
btn.onclick = function(){if(timer) return;set.setAttribute('disabled','disabled');timer = setInterval(function(){if(Number(set.value) === 0){clearInterval(timer);timer = 0;set.removeAttribute('disabled');return;}set.value = Number(set.value) - 1;},1000);
}
</script>

【2】精确倒计时

  由定时器的运行机制,我们知道每间隔1000ms去改变时间的作法并不可靠。更精确地做法,应该是与系统的运行时间作为参照,倒计时的时间变化与系统的时间变化同步,达到精确倒计时的效果 

  [注意]此部分中,需要通过取模运算和除法运算进行时、分、秒的计算,详细情况移步至此

<div id="myDiv"><label for="hour"><input type="number" id="hour" min="0" max="23" step="1" value="0" />时</label><label for="minute"><input type="number" id="minute" min="0" max="59" step="1" value="0" />分</label><label for="second"><input type="number" id="second" min="0" max="23" step="1" value="0" />秒</label><button id="btn">确定</button><button id="reset">重置</button>
</div>
<script>
var timer;
//输入限制
hour.onchange = function(){if(Number(this.value) !== Number(this.value)) this.value = 0;if(this.value > 23) this.value = 23;if(this.value < 0) this.value = 0;
}
second.onchange = minute.onchange = function(){if(Number(this.value) !== Number(this.value)) this.value = 0;if(this.value > 59) this.value = 59;if(this.value < 0) this.value = 0;
}
reset.onclick = function(){history.go();
}
btn.onclick = function(){if(timer) return;for(var i = 0; i < 3; i++){myDiv.getElementsByTagName('input')[i].setAttribute('disabled','disabled');}//原始储存值var setOri = hour.value*3600 + minute.value*60 + second.value*1;//原始系统时间值var timeOri = (new Date()).getTime();//现在所剩时间值var setNow;cancelAnimationFrame(timer);timer = requestAnimationFrame(function fn(){//当前系统时间值var timeNow = (new Date()).getTime();//使系统时间的差值与设置时间的差值相等,来获得正常的时间变化setNow = setOri - Math.floor((timeNow - timeOri)/1000);hour.value = Math.floor((setNow%86400)/3600);minute.value = Math.floor((setNow%3600)/60);second.value = Math.floor(setNow%60);timer = requestAnimationFrame(fn);if(setNow==0){cancelAnimationFrame(timer);timer = 0;btn.innerHTML = '计时结束';for(var i = 0; i < 3; i++){myDiv.getElementsByTagName('input')[i].removeAttribute('disabled');}setTimeout(function(){btn.innerHTML = '确定';},1000)            }})
}
</script>

秒表

【1】简易秒表

  秒表与倒计时的思路相同,相比而言,更加简单。每间隔100ms增加100ms即可

<div id="myDiv"><label for="set"><input id="set" value="0"></label><button id="btn">开始</button><button id="reset">重置</button>
</div>
<script>
var timer;
var con = 'off';
var num = 0;
reset.onclick = function(){history.go();
}
btn.onclick = function(){if(con === 'off'){set.setAttribute('disabled','disabled');con = 'on';btn.innerHTML = '暂停';timer = setInterval(function(){num+= 100;var minute = Math.floor(num/1000/60);var second = Math.floor(num/1000);var ms = Math.floor(num%1000)/100;set.value = minute + ' : ' + second + ' . ' + ms; },100);}else{clearInterval(timer);con = 'off';btn.innerHTML = '开始';    }
}
</script>

【2】精确秒表

  与倒计时类似,使用计时器的时间间隔作为时间变化的参照是不准确的。更精确的做法,应该是使用系统的时间变化作为秒表的变化的参照

<div id="myDiv"><label for="set"><input id="set" value="0"></label><button id="btn">开始</button><button id="reset">重置</button>
</div>
<script>
var timer;
var con = 'off';
//ori表示初始的系统时间
var ori;
//dis表示当前运行时的秒数(动态)
var dis = 0;
//last储存暂停时的秒数(静态)
var last = 0;
reset.onclick = function(){history.go();
}
btn.onclick = function(){if(con === 'off'){set.setAttribute('disabled','disabled');con = 'on';btn.innerHTML = '暂停';//保留已经走过的秒数的系统时间ori = (new Date()).getTime() - last; timer = requestAnimationFrame(function fn(){dis = (new Date()).getTime() - ori;cancelAnimationFrame(timer);timer = requestAnimationFrame(fn);var minute = Math.floor(dis/1000/60);var second = Math.floor(dis/1000);var ms = Math.floor(dis%1000);set.value = minute + ' : ' + second + ' . ' + ms; });}else{cancelAnimationFrame(timer);btn.innerHTML = '开始';    con = 'off';last = dis;}
}
</script>

闹钟

  闹钟其实就是在时钟的基础上增加一个预定时间设置,闹钟设置需要将设置时间转换成距离1970年1月1日的毫秒数,然后再算出与当前时间的差值。随着当前时间的不断增加,当差值为0时,闹钟响起

<div id="myDiv"></div>
<div id="con"><label for="hour"><input type="number" id="hour" min="0" max="23" step="1" value="0" />时</label><label for="minute"><input type="number" id="minute" min="0" max="59" step="1" value="0" />分</label><label for="second"><input type="number" id="second" min="0" max="23" step="1" value="0" />秒</label><button id="btn">确定</button><button id="reset">重置</button>
</div>
<div id="show"></div>
<script>
var timer;
//所剩时间
var dis;
myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];
setInterval(function(){myDiv.innerHTML = /\d\d:\d\d:\d\d/.exec(new Date().toString())[0];
},100);
reset.onclick = function(){history.go();
}
btn.onclick = function(){//原始储存值var setOri = hour.value*3600 + minute.value*60 + second.value*1;//原始值转换为1970年的毫秒数var setMs = +new Date(new Date().toDateString()) + setOri*1000;//如果设置的时间早于当前时间,则设置无效if(setMs < +new Date()){return;}for(var i = 0; i < 3; i++){con.getElementsByTagName('input')[i].setAttribute('disabled','disabled');}cancelAnimationFrame(timer);timer = requestAnimationFrame(function fn(){//算出设置时间与当前时间的差值dis = Math.ceil((setMs - (new Date()).getTime())/1000);var showHour = Math.floor((dis%86400)/3600);var showMinute = Math.floor((dis%3600)/60);var showSecond = Math.floor(dis%60);timer = requestAnimationFrame(fn);show.innerHTML = '距离预定时间还有 ' + showHour + '小时 ' + showMinute + '分 ' + showSecond + '秒';//当差值为0时,时间到if(dis==0){cancelAnimationFrame(timer);btn.innerHTML = '时间到了';for(var i = 0; i < 3; i++){con.getElementsByTagName('input')[i].removeAttribute('disabled');}timer = setTimeout(function(){btn.innerHTML = '确定';},1000)            }});
}
</script>

最后

  作为定时器来说,最麻烦的地方是定时器管理。如果,定时器只开启不关闭,则会造成定时器叠加效果,使得运行越来越快。所以,先关闭再启用定时器是一个好习惯

  上面四个应用加上之前的日历效果,基本囊括了关于日期和时间的应用。基本原理都类似,剩下的就是CSS美化和js代码优化问题

  欢迎交流

转载于:https://www.cnblogs.com/xiaohuochai/p/5777757.html

深入理解定时器系列第三篇——定时器应用(时钟、倒计时、秒表和闹钟)相关推荐

  1. 深入理解ajax系列第三篇——响应解码

    前面的话 我们接收到的响应主体类型可以是多种形式的,包括字符串String.ArrayBuffer对象.二进制Blob对象.JSON对象.javascirpt文件及表示XML文档的Document对象 ...

  2. 深入理解javascript作用域系列第三篇

    前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇--声明提升(hois ...

  3. javascript面向对象系列第三篇——实现继承的3种形式

    前面的话 学习如何创建对象是理解面向对象编程的第一步,第二步是理解继承.开宗明义,继承是指在原有对象的基础上,略作修改,得到一个新的对象.javascript主要包括类式继承.原型继承和拷贝继承这三种 ...

  4. 步步理解 JAVA 泛型编程 – 共三篇

    http://learning.iteye.com/blog/1295901 FROM: http://unmi.cc/understand-java-generic-3 步步理解 JAVA 泛型编程 ...

  5. [深度][PyTorch] DDP系列第三篇:实战与技巧

    [深度][PyTorch] DDP系列第三篇:实战与技巧 转自:https://zhuanlan.zhihu.com/p/250471767 零. 概览 想要让你的PyTorch神经网络在多卡环境上跑 ...

  6. arduino定时器pdf_Arduino基础入门篇18—数字时钟

    Arduino不但有外部中断,还有定时器中断,不同Arduino开发板其定时器数量及性能也各不相同,这取决于开发板主控制器.Uno R3开发板有三个定时器,本篇通过使用定时器库「TimerOne」来更 ...

  7. 【Windows编程】系列第三篇:文本字符输出

    2019独角兽企业重金招聘Python工程师标准>>> 上一篇我们展示了如何使用Windows SDK创建基本控件,本篇来讨论如何输出文本字符. 在使用Win32编程时,我们常常要输 ...

  8. 深入理解this机制系列第三篇——箭头函数

    前面的话 this机制与函数调用有关,而作用域则与函数定义有关.有没有什么是可以将this机制和作用域联系起来的呢?本文将介绍ES6新增的内容--箭头函数 痛点 对于闭包的痛点在于,闭包的this默认 ...

  9. DA1458x使用之第三篇——定时器

    用定时器可以实现一个周期性的任务,或者RTC,DA14580本身是不带RTC的. 1.首先是定义一个TIMER,在app_api.h文件的APP_MSG{}里,比如定义一个周期性任务的timer AP ...

最新文章

  1. 模拟器不全屏_iOS 14实测GBA游戏模拟器下载
  2. 个人博客满血复活,求测试~~~
  3. 信息系统项目管理师-信息化与信息系统核心知识点思维脑图
  4. 区块链技术解决物联网安全问题
  5. Nacos源码HostReactor
  6. php+剥去标签,php剥去字符串中的html与xml及php标签的函数strip_tags()
  7. 搭建基于.NetFrameWork的私有nuget服务端及打包项目发布上传
  8. 美国高校开源迄今为止最大新冠肺炎CT数据集
  9. Golang Json文件解析为结构体工具-json2go
  10. json,pickle,shelve序列化和反序列化
  11. 3h精通OpenCV(一)- 读取图像视频与网络摄像头
  12. 实现类似于百度的自动补全搜索
  13. CAM350 12.1版本安装
  14. 基于 SpringBoot + MyBatis 的在线五子棋对战
  15. CSDN博客QQ加群、微信
  16. Spring Boot-配置
  17. php ucenter home登录,UCenter Home
  18. 抖音如何推广运营?抖音如何快速涨粉?
  19. landesk桌面管理服务器安装篇
  20. 【owt-server】m88分支和m59-server

热门文章

  1. html一个页面多个动画,如何在单个html页面中添加两个相同的adobe边缘动画?
  2. robot framework好的学习网址
  3. oracle查询一张表的主键,Oracle查询表主键、外键
  4. python AES加密解密
  5. JUnit4套件测试
  6. 山东大学青岛计算机学院贺平,计算机学院学子在全国数学建模竞赛中再获佳绩...
  7. 2022年Java项目课程目录
  8. 波利亚名著《怎样解题》笔记:四步解题法
  9. 安卓实训项目:贪吃蛇V1.0
  10. C ++ 类 | 构造函数w参数_6