做一个计时器的总结
- 使用上方的HTML结构(可以根据需要自行微调)为基础编写JavaScript代码
- 当变更任何一个select选择时,更新 result-wrapper 的内容
- 当所选时间早于现在时间时,文案为 现在距离 "所选时间" 已经过去 xxxx
- 当所选时间晚于现在时间时,文案为 现在距离 "所选时间" 还有 xxxx
- 注意当前时间经过所选时间时候的文案变化
- 注意选择不同月份的时候,日期的可选范围不一样,比如1月可以选31天,11月只有30天,注意闰年
-
同样,需要注意,通过优雅的函数封装,使得代码更加可读且可维护
一 思路
- 先设置六个选择框的值,分别用循环函数
insertNode(start,end,parentNode)
插入节点注意月份值有30、31和是否闰年2月29、28的变化 - 其次为了获得结果是天时分秒,所以用当前时间-选择框的时间的秒数,可以用得到的秒数得出天数(86400s)创建
pastOrFutureTime()
函数 - 每次点击年和月的时候日期都会发生变化,所以为两者创建一个改变时间
- 把结果输出
二 总结
- 把所有的代码放在一个
(function init(){ ....... })();
的匿名自执行的函数中,可以不会生成全局变量,并且局部变量使用完之后所占的空间就会被回收了,多多把代码放进函数 - 迅雷的插件会造成
Cannot read property ‘nodeName’ of null
解决办法删除即可 - 计数器
setinterval()
如果要在一个函数中自动调用的话,需要在函数之外最少执行一次才会出发函数内部的计时器。 - 也可以在外面创建一个函数用计时器执行它
function update(){
result.innerHTML=pastOrFutureTime();
}
setInterval(update,1000);
三 具体分解如下
insertNode(start,end,parentNode)
为了插入不同的值,因为每个选择框插入的值有差别,所以传入start和end控制长度,parentNode是控制父节点的类型。
var yearNode=document.querySelector("#year-select");
var monthNode=document.querySelector("#month-select");
var dayNode=document.querySelector("#day-select");
var hourNode=document.querySelector("#hour-select");
var miniteNode=document.querySelector("#minite-select");
var secondNode=document.querySelector("#second-select");
var result=document.querySelector("#result-wrapper");
function insertNode(start,end,parentNode)//父节点,开始和结束值
{
for(var i=start;i<=end;i++)
{
var node=document.createElement("option");
node.innerHTML = i;
parentNode.appendChild(node);
}
}
insertNode(1997, 2032, yearNode);
insertNode(1, 12, monthNode);
insertNode(0, 23, hourNode);
insertNode(0, 59, miniteNode);
insertNode(0, 59, secondNode);
insertNode(1,setMonthDays(), dayNode);
1年月和时分秒都是固定值,只有月份里面的天数是不固定的,有1、3、5、7、8、10、12每月天数为31天,4、6、9、11月的天数为30,闰年的2月为29天,非闰年则为28天。所以用一个
setMonthDays()
swith语句可以方便的创建2月之外的天数,再用一个判断是否为闰年的函数isLeapYear(year)
,来为2月赋值。
function isLeapYear(year) {
return (year % 100 != 0 && year % 4 == 0) || (year % 400 == 0);//0 is false,大于0 is TRUE
}
function setMonthDays() {
var year = yearNode.value,
month = monthNode.value;
var days=0;
switch(month) {
case "1":
case "3":
case "5":
case "7":
case "8":
case "10":
case "12": days=31;
break;
case "2":if(isLeapYear(year)) {
days=29;
}
else{
days=28;
}
break;
case "4":
case "6":
case "9":
case "11": days=30;
break;
}
return days;
}
为年月创建点击事件来触发每月日期天数的变化,并且改变一次之前需要把原来的插入的节点给清空,设置值为空
window.onchange=function(e){
if(e.target==monthNode){
dayNode.innerHTML="";
insertNode(1,setMonthDays(), dayNode);
}
if(e.target==yearNode){
dayNode.innerHTML="";
insertNode(1,setMonthDays(), dayNode);
}
}
计算距离过去和未来的时间,需要用毫秒数来计算时间,首先取得选择框的值,和当前时间,创建选择框日期直接用new Date(year,month,....)就行,如果用UTC否则返回的毫秒数有误差。
如果现在时间毫秒数大于选择时间,则用now - select,否则用select - now,在这计算天数seconds / 86400需要取Math.floor()上取约数,否则会造成误差
var str="";
function pastOrFutureTime(){
var startNow = Date.now(),//现在时间距离1970年的秒数
selectSeconds,//选择的时间距离1970年的秒数
intervalSeconds,//现在时间减去选择的时间的间隔秒数
yearSelect=Number(yearNode.value),
monthSelect=Number(monthNode.value)-1,
daySelect=Number(dayNode.value),
hourSelect=Number(hourNode.value),
minitesSelect=Number(miniteNode.value),
secondsSelect=Number(secondNode.value),
diffday,
diffhour,
diffminite,
diffsecond,
flag;//命名区别符号在前面,相同者在后面比如
selectSeconds=new Date(yearSelect, monthSelect, daySelect, hourSelect, minitesSelect, secondsSelect);
if(selectSeconds < startNow)
{
intervalSeconds = (startNow - selectSeconds) / 1000;
flag=1;
}
if(selectSeconds>startNow){
intervalSeconds = (selectSeconds - startNow) / 1000;
flag=2;
}
diffday = Math.floor(intervalSeconds / 86400);
intervalSeconds = intervalSeconds % 86400;
diffhour = Math.floor(intervalSeconds / 3600);
intervalSeconds = intervalSeconds % 3600;
diffminite =Math.floor(intervalSeconds / 60);
intervalSeconds = intervalSeconds % 60;
diffsecond =Math.floor(intervalSeconds);
if(flag==1){
str="现在距离 " + yearSelect +"年" + (monthSelect+1) + "月" + daySelect + "日" +weeks[selectSeconds.getDay()]+ " 已经过去" + diffday + "天" + diffhour +"小时" + diffminite + "分" +diffsecond + "秒";
}
if(flag==2){
str="现在距离 " + yearSelect +"年" + (monthSelect+1) + "月" + daySelect + "日" +weeks[selectSeconds.getDay()]+ " 还有" + diffday + "天" + diffhour +"小时" + diffminite + "分" +diffsecond + "秒";
}
result.innerHTML=str;
setInterval(pastOrFutureTime,1000);
}
pastOrFutureTime();
result.innerHTML=str;
下面为全部代码
现在距离 2001年1月1日星期X HH:MM:SS 还有 X 天 X 小时 X 分 X 秒