18 行 JS 程式碼編一個倒時器
有時候在生活中,你需要一個JavaScript倒數計時時鐘,而不是一個末日裝置裝置。不管你是否有一次約會,銷售、促銷、或者遊戲,你可以受益於使用原生JavaScript構建一個時鐘,而不是拿到一個現成的外掛。雖然有許多很棒的時鐘外掛,但如果使用原生 JavaScript 實現,那你將得到以下好處:
- 程式碼將是輕量級的,因為它沒有依賴關係。
- 你的網站會表現得更好,因為你不需要載入外部指令碼和樣式表。
- 你將會有更高的可控性,因為你將按照想要的時鐘行為的方式來建立它(而不是找一個趨向你想法的外掛)。
所以事不宜遲,以下是如何使用僅僅18行JavaScript程式碼來做一個自己的倒數計時時鐘。
基礎時鐘:倒數計時到特定的日期或時間
以下是建立一個基礎時鐘的快速概要步驟:
- 設定一個有效的結束日期。
- 計算剩餘時間。
- 將時間轉換成可用的格式。
- 輸出時鐘資料作為一個可重用的物件。
- 在頁面上顯示時鐘,並在它到達0時停止。
設定一個有效的結束日期
首先,你需要設定一個有效的結束日期。它是JavaScript Date.parse()方法能夠解析的任何格式的一個字串。例如:
ISO 8601格式:
var deadline = ‘2015-12-31’;
短格式:
var deadline = ’31/12/2015′;
或者,長格式:
var deadline = ‘December 31 2015’;
這些格式都可以指定一個確切的時間(小時,分鐘和秒),以及時區(或者如果是ISO日期,則是UTC的偏移量)。例如:
var deadline = ‘December 31 2015 23:59:59 GMT+02:00’;
你可以在 此文閱讀更多關於JavaScript的日期格式化。
計算剩餘時間
下一步是計算剩餘時間。做到這一點,我們需要編寫一個函式,它接收一個代表給定結束時間的字串(如上所述),並計算這個時間和當前時間的差值。程式碼如下:
function getTimeRemaining(endtime){ var t = Date.parse(endtime) – Date.parse(new Date()); var seconds = Math.floor( (t/1000) % 60 ); var minutes = Math.floor( (t/1000/60) % 60 ); var hours = Math.floor( (t/(1000*60*60)) % 24 ); var days = Math.floor( t/(1000*60*60*24) ); return { ‘total’: t, ‘days’: days, ‘hours’: hours, ‘minutes’: minutes, ‘seconds’: seconds }; }
首先,我們建立一個變數t,儲存剩下的時間期限。Date.parse()函式是原生JavaScript,它將一個時間字串轉換成以毫秒為單位的值。這讓我們可以將兩個時間相減,並獲得間隔時間。
var t = Date.parse(endtime) – Date.parse(new Date());
轉換時間為可用的格式
現在我們想把毫秒轉換成天、小時、分鐘、秒。讓我們以秒為例:
var seconds = Math.floor( (t/1000) % 60 );
讓我們解釋這是怎麼回事。
- 毫秒除以1000轉換為秒:(t / 1000)
- 總秒除以60,獲取餘數——你不想要所有的秒,只是(t / 1000)%60之後的分鐘剩餘的秒數
- 將它取整,因為你想要完整的秒,而不是分數秒:Math.floor((t / 1000)% 60)
重複這個邏輯將秒轉換為分鐘、小時、天。
輸出時鐘資料作為一個可重用的物件
準備好天、小時、分鐘和秒,我們現在準備將資料作為一個可重用的物件返回:
return { ‘total’: t, ‘days’: days, ‘hours’: hours, ‘minutes’: minutes, ‘seconds’: seconds };
該物件允許你呼叫函式,得到任何已計算的值。這裡有一個如何得到剩餘分鐘的例子:
getTimeRemaining(deadline).minutes
很方便,對嗎?
在頁面上顯示時鐘,並在它到達0時停止。
現在,我們有一個函式,它可以提取天、小時、分鐘和秒,我們可以構建時鐘了。首先,我們將建立以下HTML元素來存放我們的時鐘:
<div id=”clockdiv”></div>
然後我們將編寫一個函式,輸出時鐘資料到新div:
function initializeClock(id, endtime){ var clock = document.getElementById(id); var timeinterval = setInterval(function(){ var 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。
- 如果剩餘時間到達0,停止時鐘。
到這裡,唯一剩下的步驟執行時鐘如下:
initializeClock(‘clockdiv’, deadline);
恭喜你!你現在有一個基本的時鐘,它只有短短18行JavaScript程式碼。
優化時鐘顯示
給時鐘加樣式之前,我們需要完善一點的東西。
- 移除初始載入的延遲,這樣時鐘會立即出現。
- 為了讓時鐘指令碼更有效率,不要不斷重建整個時鐘。
- 根據需要新增字首0。
移除初始載入的延遲
在時鐘中,我們用setInterval每秒鐘更新顯示。大部分時間都很好,除了一開始的時候會有一秒鐘的延遲。為了消除這個延遲,我們將不得不在間隔開始前就更新時鐘。
要做到這一點,將傳遞給setInterval(它每秒鐘更新時鐘)的匿名函式遷移到一個獨立的函式,命名為updateClock。在setInterval外呼叫updateClock一次,然後在setInterval裡面再次呼叫,這種方式,時鐘顯示的時候就沒有延遲。
在你的JavaScript中,替換:
var timeinterval = setInterval(function(){ … },1000);
為
function updateClock(){ var 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標籤內,只更新這些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變數定義的下面新增以下程式碼
var daysSpan = clock.querySelector(‘.days’); var hoursSpan = clock.querySelector(‘.hours’); var minutesSpan = clock.querySelector(‘.minutes’); var secondsSpan = clock.querySelector(‘.seconds’);
接下來,我們只需要改變updateClock函式來更新資料而不是重建整個時鐘。新程式碼是這樣的:
function updateClock(){ var 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);
如果你願意,你可以為minutes和hours新增前導零。如果你已經走了這麼遠,那麼恭喜你!你的時鐘可以顯示了。
注意:您可能需要點選CodePen中的“Rerun”來啟動倒數計時。
更進一步
下面的例子演示瞭如何為某些場景設計時鐘。他們都是基於上面的基礎例子。
自動安排時鐘
假設我們希望時鐘出現在特定的某些天。例如,我們可能會有一系列的事件出現,同時不想每次都手動更新時鐘。下面介紹如何提前進行規劃安排。
在CSS中通過設定display屬性為none來隱藏時鐘。然後新增以下程式碼到initializeClock函式(在var clock語句的後面)。這將導致時鐘只在initializeClock函式被呼叫顯示:
clock.style.display = ‘block’;
接下來,我們可以指定時鐘應該出現的時間段。這將替換deadline變數:
var 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&lt;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 &gt; currentMs &amp;&amp; currentMs &gt;= startMs ){ initializeClock(‘clockdiv’, endDate); } }
現在你可以提前安排你的時鐘,而不必手動更新它。你可以簡化程式碼。我為了可讀性寫的有點詳細。
當使用者到達倒數計時
有時有必要為一個使用者到達或開始一個特別任務的給定時間設定一個倒數計時。這裡我們將使用十分鐘,但是您可以使用任何你想要的時間。
所有我們需要做的是將deadline變數替換為:
var timeInMinutes = 10; var currentTime = Date.parse(new Date()); var deadline = new Date(currentTime + timeInMinutes*60*1000);
這段程式碼將當前時間增加了十分鐘。再轉換為毫秒,所以他們可以相加在一起,並轉換成一個新的截止日期。
現在我們有一個時鐘,在十分鐘使用者到達時倒數計時。請隨便玩,嘗試不同的時間長度。
跨頁面保持時鐘
有時有必要不僅僅為當前頁面保持時鐘的狀態。例如,如果我們希望整個網站有一個十分鐘的倒數計時,我們不希望每次使用者進入不同的頁面或每次使用者重新整理頁面時重置時鐘。
一個解決方案是將時鐘的結束時間儲存在cookie。這樣,導航到一個新的頁面不會重置結束時間為十分鐘。
邏輯是這樣的:
- 如果deadline記錄在一個cookie中,使用deadline。
- 如果cookie不存在,建立一個新的deadline並將它儲存在一個cookie中。
為了實現這一點,如下替換deadline變數:
// if there’s a cookie with the name myClock, use that value as the deadline if(document.cookie &amp;&amp; document.cookie.match(‘myClock’)){ // get deadline value from cookie var deadline = document.cookie.match(/(^|myClock=([^;]+)/)[2]; } // otherwise, set a deadline 10 minutes from now and // save it in a cookie with that name else{ // create deadline 10 minutes from now var timeInMinutes = 10; var currentTime = Date.parse(new Date()); var deadline = new Date(currentTime + timeInMinutes*60*1000); // store deadline in cookie for future reference document.cookie = ‘myClock=’ + deadline + ‘; path=/; domain=.yourdomain.com’; }
這段程式碼使用了 cookies 和正規表示式,這兩部分是分開的。出於這個原因,我不會講太多的細節。需要注意的一個重要的事情是,你需要將.yourdomain.com替換成真實的域。如果你對此有任何問題,在評論中讓我知道。
關於客戶端時間的一個重要的警告
JavaScript的日期和時間從使用者的計算機上獲取。這意味著使用者可以通過改變機器的時間來影響一個JavaScript時鐘。在大多數情況下,這並不重要,但是對於一些超級敏感的情況,有必要從伺服器獲取時間。這可以使用PHP或Ajax,兩者都是超出了本教程的範圍。
在任何情況下,從伺服器獲取時間後,我們可以使用和本教程相同的客戶端技術來使用它。
總結
我們已經介紹瞭如何做一個基礎的倒數計時時鐘和進行有效的顯示。我們也學習了計劃時鐘,絕對與相對時間,跨頁面保持時鐘的狀態。
下一步?
玩時鐘程式碼。嘗試新增一些有創意的樣式,或新功能(如暫停和恢復按鈕)。如果你想出任何酷炫時鐘的例子,且你想要和我們分享,或者對以上內容有任何疑問,請在評論中讓我知道。
相關文章
- 一行程式碼,瀏覽器變臨時編輯器行程瀏覽器
- 僅一行程式碼,打造一個線上編輯器行程
- js自動倒數計時程式碼,倒數計時完畢時自動停止迴圈JS
- JS簡單的倒數計時(程式碼優化)JS優化
- 實時程式碼編輯器
- 編寫一個簡易計時器程式(edu)
- js倒數計時關閉頁面程式碼例項JS
- js倒數計時關閉當前頁面程式碼JS
- js程式碼實現倒數計時秒殺的效果JS
- cell (iOS表格) - 簡單實現一個定時器管理600個倒數計時 - 2.程式碼介紹篇iOS定時器
- 幾百行程式碼實現一個 JSON 解析器行程JSON
- js——倒數計時JS
- JS倒數計時JS
- 70 行 Python 程式碼編寫一個遞迴下降解析器Python遞迴
- js實現驗證碼倒數計時JS
- JavaScript 倒數計時60秒程式碼JavaScript
- JavaScript倒數計時程式碼例項JavaScript
- setTimeout倒數計時效果程式碼
- 倒數計時(Excel程式碼集團)Excel
- js倒數計時 實現傳送驗證碼倒數計時60sJS
- 同時開左右兩個SAPGUI編輯器顯示同一段ABAP程式碼GUI
- 一百行js程式碼實現一個校驗工具JS
- Kookjs 倒數計時JS
- [Unity]記一個倒數計時介面Unity
- 寫程式碼時,編譯器比你聰明編譯
- 10個線上HTML程式碼編輯器HTML
- js檢測一段程式碼的執行消耗時間JS
- 小程式 - 驗證碼倒數計時元件元件
- jQuery倒數計時效果程式碼例項jQuery
- JavaScript春節倒數計時程式碼例項JavaScript
- 7個殺手級的JS一行程式碼JS行程
- 60 行 JS 程式碼搞定一個下拉重新整理元件JS元件
- js驗證碼重新傳送倒數計時效果JS
- .NET程式碼樹執行時間計時器
- iOS中一句程式碼解決倒數計時問題iOS
- 如何控制 Go 編碼 JSON 資料時的行為GoJSON
- 前端與編譯原理——用 JS 寫一個 JS 直譯器前端編譯原理JS
- 前端與編譯原理——用JS寫一個JS直譯器前端編譯原理JS