可以詳細的講一下平時網頁上做活動時的倒計時是怎麼實現的嗎?


&
&
&
&
&倒計時&
&

----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 | 前端工程師 |