18行JavaScript代碼構建一個倒數計時器
有時,您將需要構建一個JavaScript倒數時鐘。您可能有活動,銷售,促銷或遊戲。您可以使用原始JavaScript構建時鐘,而不用尋找最近的插件。雖然有很多很棒的時鐘插件,但是使用原始JavaScript可以帶來以下好處:
- 您的代碼將是輕量級的,因爲它將具有零依賴性。
- 您的網站將表現更好。您無需加載外部腳本和樣式表。
- 您將擁有更多控制權。您將構建時鐘,使其行爲完全符合您希望的方式(而不是嘗試將插件彎曲到您的意願)
因此,事不宜遲,這裏介紹瞭如何僅用18行JavaScript來製作自己的倒計時時鐘。
基本時鐘:倒數到特定的日期或時間
- 設置有效的結束日期。
- 計算剩餘時間。
- 將時間轉換爲可用格式。
- 將時鐘數據輸出爲可重複使用的對象。
- 在頁面上顯示時鐘,並在時鐘爲零時停止時鐘。
設定有效的結束日期
首先,您需要設置一個有效的結束日期。這應該是JavaScript的Date.parse()
方法可以解析的任何格式的字符串。例如:
1、在ISO 8601格式:
const deadline = '2015-12-31';
2、簡短格式:
const deadline = '31/12/2015';
3、或者,長格式:
const deadline = 'December 31 2015';
4、這些格式中的每一種都允許您指定確切的時間和時區(對於ISO日期,則爲UTC的偏移量)。例如:
const deadline = 'December 31 2015 23:59:59 GMT+0200';
計算剩餘時間
下一步是計算剩餘時間。我們需要編寫一個函數,該函數需要一個表示給定結束時間的字符串(如上所述)。然後,我們計算該時間與當前時間之間的時差。看起來像這樣:
function getTimeRemaining(endtime){
const total = Date.parse(endtime) - Date.parse(new Date());
const seconds = Math.floor( (total/1000) % 60 );
const minutes = Math.floor( (total/1000/60) % 60 );
const hours = Math.floor( (total/(1000*60*60)) % 24 );
const days = Math.floor( total/(1000*60*60*24) );
return {
total,
days,
hours,
minutes,
seconds
};
}
首先,我們創建一個變量total
,以保留剩餘時間直到截止日期。該Date.parse()
函數將時間字符串轉換爲毫秒值。這使我們可以相減兩次,並獲得兩者之間的時間量。
const total = Date.parse(endtime) - Date.parse(new Date());
將時間轉換爲可用格式
現在,我們要將毫秒轉換爲天,小時,分鐘和秒。讓我們以秒爲例:
const seconds = Math.floor( (t/1000) % 60 );
讓我們分解一下這裏發生的事情。
- 將毫秒除以1000可轉換爲秒:
(t/1000)
- 將總秒數除以60,然後取餘數。您不希望所有的秒數,僅需要計算分鐘數之後剩下的秒數:
(t/1000) % 60
- 四捨五入到最接近的整數。這是因爲您需要完整的秒數,而不是幾分之一秒:
Math.floor( (t/1000) % 60 )
重複此邏輯,將毫秒轉換爲分鐘,小時和天。
輸出時鐘數據作爲可重用對象
準備好幾天,幾小時,幾分鐘和幾秒鐘之後,我們現在可以將數據作爲可重用的對象返回:
getTimeRemaining(deadline).minutes
顯示時鐘並在達到零時停止
現在,我們有了一個可以花費剩餘的天,小時,分鐘和秒的功能,我們可以構建時鐘了。首先,我們將創建以下HTML元素來保存時鐘:
<div id="clockdiv"></div>
然後,我們將編寫一個在新div中輸出時鐘數據的函數:
function initializeClock(id, endtime) {
const clock = document.getElementById(id);
const timeinterval = setInterval(() => {
const t = getTimeRemaining(endtime);
clock.innerHTML = 'days: ' + t.days + '<br>' +
'hours: '+ t.hours + '<br>' +
'minutes: ' + t.minutes + '<br>' +
'seconds: ' + t.seconds;
if (t.total <= 0) {
clearInterval(timeinterval);
}
},1000);
}
該函數有兩個參數。這些是包含我們時鐘的元素的ID,以及倒計時的結束時間。在函數內部,我們將聲明一個clock
變量並將其用於存儲對我們的時鐘容器div的引用。這意味着我們不必繼續查詢DOM。
接下來,我們將使用setInterval
每秒執行一個匿名函數。此功能將執行以下操作:
- 計算剩餘時間。
- 將剩餘時間輸出到我們的div。
- 如果剩餘時間爲零,請停止計時。
此時,剩下的唯一步驟是像這樣運行時鐘:
initializeClock('clockdiv', deadline);
恭喜你!現在,您僅用18行JavaScript就擁有了一個基本時鐘。
準備顯示時鐘
在設置時鐘樣式之前,我們需要進行一些細化。
- 消除初始延遲,使您的時鐘立即顯示。
- 提高時鐘腳本的效率,以免持續重建整個時鐘。
- 根據需要添加前導零。
消除初始延遲
在時鐘中,我們習慣於setInterval
每秒更新一次顯示。多數情況下,這很好,除非在開始時會有一秒鐘的延遲。要消除此延遲,我們必須在間隔開始之前更新一次時鐘。
讓我們將要傳遞給setInterval
它的匿名函數移到其自己的獨立函數中。我們可以命名這個函數updateClock
。在updateClock
外部調用該函數setInterval
,然後在內部再次調用setInterval
。這樣,時鐘顯示就沒有延遲了。
在您的JavaScript中,替換爲:
const timeinterval = setInterval(() => { ... },1000);
有了這個:
function updateClock(){
const t = getTimeRemaining(endtime);
clock.innerHTML = 'days: ' + t.days + '<br>' +
'hours: '+ t.hours + '<br>' +
'minutes: ' + t.minutes + '<br>' +
'seconds: ' + t.seconds;
if (t.total <= 0) {
clearInterval(timeinterval);
}
}
updateClock(); // run function once at first to avoid delay
var timeinterval = setInterval(updateClock,1000);
避免持續重建時鐘
我們需要使時鐘腳本更高效。我們只想更新時鐘中的數字,而不是每秒重新構建整個時鐘。實現此目的的一種方法是將每個數字放在span標籤中,然後僅更新這些跨度的內容。
這是HTML:
<div id="clockdiv">
Days: <span class="days"></span><br>
Hours: <span class="hours"></span><br>
Minutes: <span class="minutes"></span><br>
Seconds: <span class="seconds"></span>
</div>
現在讓我們參考這些元素。在clock定義變量的位置之後添加以下代碼
const daysSpan = clock.querySelector('.days');
const hoursSpan = clock.querySelector('.hours');
const minutesSpan = clock.querySelector('.minutes');
const secondsSpan = clock.querySelector('.seconds');
接下來,我們需要更改updateClock功能以僅更新數字。新代碼如下所示:
function updateClock(){
const t = getTimeRemaining(endtime);
daysSpan.innerHTML = t.days;
hoursSpan.innerHTML = t.hours;
minutesSpan.innerHTML = t.minutes;
secondsSpan.innerHTML = t.seconds;
...
}
添加前導零
現在時鐘不再每秒都在重建,我們還有另一件事要做:添加前導零。例如,不是讓時鐘顯示7秒,而是顯示07秒。一種簡單的方法是在數字的開頭添加字符串“ 0”,然後切掉最後兩位數字。
例如,要在“ seconds”值上添加前導零,您可以對此進行更改:
secondsSpan.innerHTML = t.seconds;
對此:
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
如果需要,您也可以在分鐘和小時中添加前導零。如果您走了這麼遠,恭喜!您的時鐘現在可以顯示了。
注意:您可能需要在CodePen中單擊“重新運行”才能開始倒計時。
自動安排時鐘
假設我們希望時鐘顯示在某些日子,而不是其他日子。例如,我們可能會發生一系列事件,並且不想每次都手動更新時鐘。這是提前安排事情的方法。
通過在CSS中將其display
屬性設置爲隱藏時鐘none
。然後將以下內容添加到initializeClock
函數中(以開頭的行之後var clock
)。一旦initializeClock
調用此函數,這將導致時鐘僅顯示:
clock.style.display = 'block';
接下來,我們可以指定顯示時鐘的日期。這將替換deadline
變量:
const schedule = [
['Jul 25 2015', 'Sept 20 2015'],
['Sept 21 2015', 'Jul 25 2016'],
['Jul 25 2016', 'Jul 25 2030']
];
schedule
數組中的每個元素代表一個開始日期和一個結束日期。如上所述,可以包括時間和時區,但是我在這裏使用了簡單的日期來保持代碼的可讀性。
最後,當用戶加載頁面時,我們需要檢查是否在指定的時間範圍內。該代碼應替換先前對該initializeClock
函數的調用。
// iterate over each element in the schedule
for (var i=0; i<schedule.length; i++) {
var startDate = schedule[i][0];
var endDate = schedule[i][1];
// put dates in milliseconds for easy comparisons
var startMs = Date.parse(startDate);
var endMs = Date.parse(endDate);
var currentMs = Date.parse(new Date());
// if current date is between start and end dates, display clock
if (endMs > currentMs && currentMs >= startMs ) {
initializeClock('clockdiv', endDate);
}
}
schedule.forEach(([startDate, endDate]) => {
// put dates in milliseconds for easy comparisons
const startMs = Date.parse(startDate);
const endMs = Date.parse(endDate);
const currentMs = Date.parse(new Date());
// if current date is between start and end dates, display clock
if (endMs > currentMs && currentMs >= startMs ) {
initializeClock('clockdiv', endDate);
}
});
現在,您可以提前安排時鐘,而無需手動更新。您可以根據需要縮短代碼。爲了便於閱讀,我讓我變得冗長。
從用戶到達起將計時器設置爲10分鐘
用戶到達或開始特定任務後,有必要在給定的時間內設置倒計時。我們將在此處將計時器設置爲10分鐘,但是您可以使用任意時間。
我們需要做的就是deadline
用這個替換變量:
const timeInMinutes = 10;
const currentTime = Date.parse(new Date());
const deadline = new Date(currentTime + timeInMinutes*60*1000);
該代碼將花費當前時間,並增加十分鐘。這些值將轉換爲毫秒,因此可以將它們加在一起並變成新的截止日期。
現在,我們有了一個時鐘,可以從用戶到達時開始倒數十分鐘。隨意玩耍,嘗試不同的時間長度。
跨頁面保持時鐘進度
有時,有必要將時鐘狀態保留的時間不僅限於當前頁面。如果我們要在整個網站上設置10分鐘的計時器,則我們不希望在用戶轉到其他頁面時重置該計時器。
一種解決方案是將時鐘的結束時間保存在cookie中。這樣,導航到新頁面不會將結束時間重置爲現在的十分鐘。
這是邏輯:
- 如果Cookie中記錄了截止日期,請使用該截止日期。
- 如果不存在該cookie,則設置一個新的截止日期並將其存儲在cookie中。
要實現這一點,請用deadline
以下內容替換變量:
let deadline;
// if there's a cookie with the name myClock, use that value as the deadline
if(document.cookie && document.cookie.match('myClock')){
// get deadline value from cookie
deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
} else {
// otherwise, set a deadline 10 minutes from now and
// save it in a cookie with that name
// create deadline 10 minutes from now
const timeInMinutes = 10;
const currentTime = Date.parse(new Date());
deadline = new Date(currentTime + timeInMinutes*60*1000);
// store deadline in cookie for future reference
document.cookie = 'myClock=' + deadline + '; path=/; domain=.yourdomain.com';
}
這段代碼利用了cookie
和正則表達式
,它們本身就是單獨的主題。因此,我在這裏不再贅述。需要注意的一件事是,您需要更改yourdomain.com
爲實際域。
有關客戶端時間的重要警告
avaScript日期和時間是從用戶計算機中獲取的。這意味着用戶可以通過更改計算機上的時間來影響JavaScript時鐘。在大多數情況下,這無關緊要。但是,在某些超級敏感的情況下,有必要從服務器獲取時間。可以使用一些PHP或Ajax來完成,這兩者都超出了本教程的範圍。
從服務器獲取時間後,我們可以使用本教程中的相同技術來使用它。
總結
在閱讀完本文中的示例之後,您現在知道如何僅用幾行原始JavaScript代碼創建自己的倒數計時器!我們已經研究瞭如何製作基本的倒數時鐘並有效顯示它。我們還介紹了添加一些有用的附加功能,包括計劃,絕對時間和相對時間,以及使用Cookie保留頁面和站點訪問之間的狀態。