今天開需求評(píng)審會(huì),看原型文檔里面有一板塊是一個(gè)天:時(shí):分:秒
的倒計(jì)時(shí)。開完會(huì)睦授,去項(xiàng)目的模塊里看了看院崇,WTF,居然沒有倒計(jì)時(shí)的模塊,那只有自己寫一個(gè)了闲询。
首先久免,后臺(tái)返回的是以毫秒為單位的時(shí)間,那來看思路=>
假如扭弧,現(xiàn)在有一時(shí)間段是1234567899ms阎姥。
換算一下:1234567899ms == 1234567.899s
。這里我們可以把0.899s
省去鸽捻,先保留整數(shù)來換算呼巴,稍后再來處理0.899s
。
以下是換算過程:
1234567/60 => 20576分+7秒
20576/60 => 342小時(shí)+56分
342/24 => 14天 + 6小時(shí)
經(jīng)過以上換算過程御蒲,根據(jù)倒計(jì)時(shí)格式衣赶,對(duì)應(yīng)的就是14天:6小時(shí):56分:7秒
,在這個(gè)基礎(chǔ)上厚满,一秒一秒的往下走府瞄,也就是1234567依次--,直到0碘箍;
返回來說剩余的0.899s
,受到iphone上秒表的啟發(fā)遵馆,毫秒部分的倒計(jì)時(shí)是以兩位來進(jìn)行的,如下圖:
毫秒位是從0到99敲街,也就是每1毫秒加1团搞,直到增加到99,然后進(jìn)位多艇,秒數(shù)加1逻恐,所以按照這個(gè)原理,我們可以把多余的
0.899s
保留兩位小數(shù)峻黍,也就是0.899.toFixed(2) => 0.90
复隆,這里換算出來的就是四舍五入以后的值,然后取小數(shù)點(diǎn)后的值姆涩,也就是90挽拂。在倒計(jì)時(shí)進(jìn)行前,先把
0.90s
消耗完骨饿,也就是以每1毫秒減1的速度從90減到0亏栈,然后再運(yùn)行倒計(jì)時(shí)台腥。所以,在這個(gè)思路中绒北,有兩個(gè)倒計(jì)時(shí)黎侈,一個(gè)是消耗0.90s
的倒計(jì)時(shí),一個(gè)是咱們需要展示在頁面上的倒計(jì)時(shí)闷游。
以下是全部代碼峻汉。
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id='countDown'></div>
</body>
<script>
function TimeDown(ele,opt,cb){
ele = ele.indexOf('#') == 0?document.getElementById(ele.replace('#','')):(ele.indexOf('.') == 0?document.getElementsByClassName(ele.replace('.',''))[0]:console.error('ele is classname or id'))
var tt = this;
var TD = {
dealToPend:function(s,ele){
var sa = s.split(':');
var sal = sa.length;
var st = '';
for(var i=0;i<sal;i++){
sa[i] = sa[i].toString().length == 1?'0'+sa[i]:sa[i];
st+=sa[i]+':';
}
ele.innerHTML = st.substring(0,st.length-1);
},
dd:function(int){
var dd = Math.floor(Math.floor(Math.floor(int/60)/60)/24);
var hh = Math.floor(Math.floor(int/60)/60)%24;
var mm = Math.floor(int/60)%60;
var ss = int%60;
return dd+':'+hh+':'+mm+':'+ss;
},
hh:function(int){
var hh = Math.floor(int/60/60);
var mm = Math.floor(int/60)%60;
var ss = int%60;
return hh+':'+mm+':'+ss;
},
mm:function(int){
var mm = Math.floor(int/60);
var ss = int%60;
return mm+':'+ss;
}
}
tt.time = Math.floor(tt/1000);
tt.f = '';
tt.dealInt = function(int){
var tdt = setInterval(function(){
if(int == 1){
clearInterval(tdt);
if(cb){
cb();
}
return;
}
int--;
TD.dealToPend(TD[opt](int),ele);
},1000)
}
tt.dealFloat = function(float,int){
var fdt = setInterval(function(){
if(float == 0){
clearInterval(fdt);
tt.dealInt(int);
}
float--;
},1)
}
tt.dealFloatms = function(){
tt.f = (tt/1000-tt.time).toFixed(2)*100;
tt.dealFloat(tt.f,tt.time);
}
//避免page load出現(xiàn)短暫空白時(shí)間
TD.dealToPend(TD[opt](tt.time),ele);
//是否存在不夠一秒的情況
tt%1000 != 0?tt.dealFloatms():tt.dealInt(tt.time);
}
Number.prototype.timedown = TimeDown;
var differ = new Date('2018-05-16 24:00').getTime() - new Date().getTime();
var fn = function(){
document.getElementById('countDown').innerHTML = 'time is up';
}
//第一個(gè)參數(shù)是用于盛放倒計(jì)時(shí)元素的id或者classname
//第二個(gè)參數(shù)是倒計(jì)時(shí)格式
//'dd':代表 天:小時(shí):分:秒
//'hh':代表 小時(shí):分:秒
//'mm':代表 分:秒
//目前只支持以上三種格式
//第三個(gè)參數(shù)是倒計(jì)時(shí)結(jié)束的回調(diào)
differ.timedown('#countDown','dd',fn);
</script>
</html>
這其中可能有不到1毫秒的誤差,甚至不到0.01毫秒脐往,因?yàn)樵趕etInterval和setTimeout兩個(gè)方法中休吠,只有執(zhí)行次數(shù)到千萬甚至億級(jí)別,才有不到1毫秒的誤差业簿,所以誤差在0.01毫秒級(jí)別的可以省略瘤礁。感興趣的可以用time和timeEnd試一試。