可以詳細的講一下平時網頁上做活動時的倒計時是怎麼實現的嗎?
&
&
&
&
&
&
&
&
&
&
&距離2055年10月1日中午12點還有:&
&&天
&&時
&&分
&&秒
&
&
&
這個是DEMO 倒計時
如果需要更高精確度,需要與後端進行溝通,優化setInterval()函數。
----2015.3.21 更新
如果系統時間是錯誤的,可以利用與伺服器溝通,獲得時間。var xhr = new XMLHttpRequest();
//這裡的testServer.txt,其實我沒有創建,完全可以不需要這個文件,我們只是要時間罷了
xhr.open("get", "testServer.txt", true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 3){ //狀態3響應
var header = xhr.getAllResponseHeaders(); //獲得所有的頭信息
alert(header);//會彈出一堆信息
//彈出時間,那麼可以利用獲得的時間做倒計時程序了。
alert(xhr.getResponseHeader("Date"));
}
}
xhr.send(null);
參考自 2011年9月23日,百度前端面試題對話記錄(2)
注意:當然通過通過XHR.readyState == 4也可以獲得獲得伺服器時間,上面的代碼知識為了證明:interactive狀態就可以獲得http頭部內容優化setInterval:想了了,即使利用setTimeout()模擬setInterval(),還是會因為其餘腳本的執行,造成誤差。所以,我認為setInterval的弊端無法避免,只能通過多次與伺服器溝通,來矯正時間。你可以看看這個資料:由秒殺活動想到的 · Issue #13 · fwon/blog · GitHub
@李力的回答挺好的,就是代碼擼的有點不具體,花了半小時,擼了一個包含上面所說的內容的具體實現。
(function() {
function timer(delay) {
var self = this;
this._queue = [];
setInterval(function() {
for (var i = 0; i &< self._queue.length; i++) {
self._queue[i]();
}
},
delay);
}
timer.prototype = {
constructor: timer,
add: function(cb) {
this._queue.push(cb);
return this._queue.length - 1;
},
remove: function(index) {
this._queue.splice(index, 1);
}
};
var delayTime = 1000;
var msInterval = new timer(delayTime);
function countDown(config) {
var defaultOptions = {
fixNow: 3 * 1000,
fixNowDate: false,
now: new Date().valueOf(),
template: "{d}:{h}:{m}:{s}",
render: function(outstring) {
console.log(outstring);
},
end: function() {
console.log("the end!");
},
endTime: new Date().valueOf() + 5 * 1000 * 60
};
for (var i in defaultOptions) {
this[i] = config[i] || defaultOptions[i];
}
this.init();
}
countDown.prototype = {
constructor: countDown,
init: function() {
var self = this;
if (this.fixNowDate) {
var fix = new timer(this.fixNow);
fix.add(function() {
self.getNowTime(function(now) {
self.now = now;
});
});
}
var index = msInterval.add(function() {
self.now += delayTime;
if (self.now &>= self.endTime) {
msInterval.remove(index);
self.end();
} else {
self.render(self.getOutString());
}
});
},
getBetween: function() {
return _formatTime(this.endTime - this.now);
},
getOutString: function() {
var between = this.getBetween();
return this.template.replace(/{(w*)}/g, function(m, key) {
return between.hasOwnProperty(key) ? between[key] : "";
});
},
getNowTime: function(cb) {
var xhr = new XMLHttpRequest();
xhr.open("get", "/", true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 3) {
var now = xhr.getResponseHeader("Date");
cb(new Date(now).valueOf());
}
};
xhr.send(null);
}
};
function _cover(num) {
var n = parseInt(num, 10);
return n &< 10 ? "0" + n: n;
}
function _formatTime(ms) {
var s = ms / 1000,
m = s / 60;
return {
d: _cover(m / 60 / 24),
h: _cover(m / 60 % 24),
m: _cover(m % 60),
s: _cover(s % 60)
};
}
var now = Date.now();
new countDown({});
new countDown({
endTime: now + 8 * 1000
});
})();
可以在node下跑也可以在web下跑,不依賴任何東東,擴展性也還不錯,支持配置定時與伺服器對錶,簡易模板替換,結束時回調,公用定時器等優化與功能,不愛寫注釋,應該看代碼很直觀就能懂啦。
XD。
設置了同步時間機制,就請求的當前域首頁,更新當前時間就ok了,可以把代碼直接拷貝到控制台看效果。。。
當然你還可以繼續豐富代碼,比如還能隨時關閉同步,隨時替換模板樣式和內容等等等等。。盡情的擼吧。。推薦閱讀:
※北京的web前端是不是快飽和了?
※SCSS和LESS相比有什麼優勢?Bootstrap 4也要改成SCSS默認的了
※似乎,SASS的首選開發框架不是compass了?甚至不用專門SASS開發框架了?
※如何讓web返回上一頁時恢上次復瀏覽位置?
TAG:前端開發 | JavaScript | 前端工程師 |