共计 6282 个字符,预计需要花费 16 分钟才能阅读完成。
首发于公众号:《前端全栈开发者》
原文:https://www.sitepoint.com
作者:Nilson Jacques
有时候,你会须要构建一个 JavaScript 倒计时时钟。你可能会有一个流动、一个销售、一个促销或一个游戏。你能够用原生的 JavaScript 构建一个时钟,而不是去找一个插件。只管有很多很棒的时钟插件,然而应用原生 JavaScript 能够带来以下益处:
- 你的代码将是轻量级的,因为它将具备零依赖性。
- 你的网站将体现得更好。你不须要加载内部脚本和样式表。
- 你将领有更多的控制权。你将会建设一个齐全依照你的志愿来体现的时钟。
所以,废话不多说,上面是如何在短短的 18 行 JavaScript 中制作本人的倒计时钟。
1. 根本时钟:倒数到特定的日期或工夫
以下是创立根本时钟所需步骤的简要概述:
- 设置无效的完结日期。
- 计算剩余时间。
- 将工夫转换为可用格局。
- 将时钟数据输入为可重复使用的对象。
- 在页面上显示时钟,并在时钟为零时进行时钟。
2. 设置无效的完结日期
首先,你须要设置一个无效的完结日期。这应该是 JavaScript 的 Date.parse() 办法能够了解的任何格局的字符串。例如:
ISO 8601 格局:
const deadline = '2015-12-31';
简短格局:
const deadline = '31/12/2015';
或者,长格局:
const deadline = 'December 31 2015';
这些格局中的每一种都容许你指定一个精确的工夫和一个时区(或者在 ISO 日期的状况下指定一个与 UTC 的偏移)。例如:
const deadline = 'December 31 2015 23:59:59 GMT+0200';
3. 计算剩余时间
下一步是计算剩余时间。咱们须要编写一个函数,该函数须要一个示意给定完结工夫的字符串(如上所述)。而后,咱们计算该工夫与以后工夫之间的时差。看起来像这样:
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());
4. 将工夫转换为可用格局
当初咱们要将毫秒转换为天,小时,分钟和秒。让咱们以秒为例:
const seconds = Math.floor((t/1000) % 60 );
让咱们合成一下这里产生的事件。
- 将毫秒除以 1000 可转换为秒:
(t/1000)
- 将总秒数除以 60,而后取余数。你不须要所有的秒,只须要计算分钟数后剩下的那些:
(t/1000) % 60
- 四舍五入到最靠近的整数。这是因为你须要残缺的秒数,而不是几分之一秒:
Math.floor((t/1000)%60)
反复此逻辑,将毫秒转换为分钟,小时和天。
5. 将时钟数据输入为可重复使用的对象
在筹备好几天,几小时,几分钟和几秒钟之后,咱们当初能够将数据作为可重复使用的对象返回:
return {
total,
days,
hours,
minutes,
seconds
};
这个对象容许你调用你的函数,并取得任何计算值。这是如何获取残余分钟数的示例:
getTimeRemaining(deadline).minutes
不便吧?
6. 在页面上显示时钟,并在时钟为零时进行时钟
当初咱们有了一个能够吐出残余天数、小时、分钟和秒数的函数,咱们就能够建设咱们的时钟了。首先,咱们将创立以下 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 就领有了一个根本时钟。
7. 筹备展现你的时钟
在设置时钟款式之前,咱们须要进行一些改良。
- 打消初始提早,使你的时钟立刻显示。
- 让时钟脚本更有效率,这样它就不会间断重建整个时钟。
- 依据须要增加前导零。
7.1 打消初始提早
在时钟中,咱们应用 setInterval
每秒更新一次显示。少数状况下,这很好,除非在开始时会有一秒钟的提早。要打消此提早,咱们必须在距离开始之前更新一次时钟。
让咱们将传递给 setInterval
的匿名函数移到其本人的独自函数中,咱们能够将此函数命名为 updateClock
。在 setInterval
外调用一次 updateClock
函数,而后在 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(); // 首先运行一函数能以防止提早
var timeinterval = setInterval(updateClock,1000);
7.2 防止一直重建时钟
咱们须要使时钟脚本更高效,咱们只想更新时钟中的数字,而不是每秒重建整个时钟。实现此目标的一种办法是将每个数字放在 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
变量的地位之后增加以下代码
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.3 增加前导 0
当初时钟不再每秒都在重建,咱们还有另一件事要做:增加前导零。例如,不是让时钟显示 7 秒,而是显示 07 秒。一种简略的办法是在一个数的结尾加上一串“0”,而后切掉最初两个数字。
例如,要在“seconds”值上增加前导零,你能够更改以下设置:
secondsSpan.innerHTML = t.seconds;
为
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
如果你违心,你也能够在分钟和小时的后面加零。如果你曾经走到这一步,祝贺你!你的时钟当初曾经能够显示了。
8. 更进一步
以下示例演示了如何为某些用例扩大时钟。它们都是基于下面的根本例子。
8.1 主动调节时钟
假如咱们想让时钟在特定的日子呈现,而不是在其余的日子。例如,咱们可能有一系列事件行将产生,而不心愿每次都手动更新时钟。以下是如何提前安顿事件的办法。
通过在 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
函数的调用:
// 遍历 schedule 中的每个元素
schedule.forEach(([startDate, endDate]) => {
// 以毫秒为单位搁置日期以便于比拟
const startMs = Date.parse(startDate);
const endMs = Date.parse(endDate);
const currentMs = Date.parse(new Date());
// 如果以后日期在开始日期和完结日期之间,则显示时钟
if (endMs > currentMs && currentMs >= startMs) {initializeClock('clockdiv', endDate);
}
});
当初,你能够提前安顿你的时钟,而不用手动更新它。如果你违心,你能够缩短代码。为了便于浏览,我把我的代码写得很啰嗦。
8.2 从用户达到起将计时器设置为 10 分钟
用户达到或开始特定工作后,有必要在给定的工夫内设置倒计时。咱们将在此处将计时器设置为 10 分钟,然而你能够应用任意工夫。
咱们须要做的就是用以下命令替换 deadline
变量:
const timeInMinutes = 10;
const currentTime = Date.parse(new Date());
const deadline = new Date(currentTime + timeInMinutes*60*1000);
这段代码以以后工夫为基准,减少 10 分钟。这些值将转换为毫秒,因而能够将它们加在一起并变成新的截止日期。
当初咱们有一个时钟,从用户达到时开始倒计时十分钟,你能够自由发挥,尝试不同的工夫长度。
8.3 跨页面放弃时钟进度
有时,除了以后页面外,还须要保留时钟状态。如果咱们想在整个网站上设置 10 分钟的计时器,则咱们不心愿在用户转到其余页面时重置该计时器。
一个解决方案是将时钟的完结工夫保留在一个 cookie 中。这样一来,导航到一个新的页面就不会把完结工夫重置到十分钟当前。
这是逻辑:
- 如果 Cookie 中记录了截止日期,应用该截止日期。
- 如果不存在 Cookie,请设置一个新的截止日期并将其存储在 Cookie 中。
要实现这一点,请应用以下命令替换 deadline
变量:
let deadline;
// 如果有一个名为 myClock 的 cookie,则应用该值作为截止日期
if(document.cookie && document.cookie.match('myClock')){
// 从 Cookie 获取截止日期值
deadline = document.cookie.match(/(^|;)myClock=([^;]+)/)[2];
} else {
// 否则,请设置从当初开始 10 分钟的截止日期,// 将其保留在具备该名称的 cookie 中
// 创立从当初开始 10 分钟的截止日期
const timeInMinutes = 10;
const currentTime = Date.parse(new Date());
deadline = new Date(currentTime + timeInMinutes*60*1000);
// 将截止日期存储在 cookie 中以供未来援用
document.cookie = 'myClock=' + deadline + '; path=/; domain=.yourdomain.com';
}
须要留神的是,你须要将 .yourdomain.com
改为你的理论域名。
9. 无关客户端工夫的重要正告
JavaScript 日期和工夫是从用户的计算机上获取的,这意味着用户能够通过更改计算机上的工夫来影响 JavaScript 时钟。在大多数状况下,这并不重要,但在一些超级敏感的状况下,就须要从服务器上获取工夫。能够应用一些 Node.js 或 Ajax 来实现,这两者都超出了本教程的范畴。
从服务器获取工夫后,咱们能够应用本教程中的雷同技术来应用它。
10. 总结
在实现本文中的示例之后,你当初晓得了如何应用几行简略的 JavaScript 代码创立本人的倒计时计时器!咱们曾经理解了如何制作一个根本的倒计时时钟并无效地显示它。咱们还介绍了增加一些有用的附加性能,包含日程安排、相对工夫与绝对工夫,以及在页面和网站拜访之间用 cookie 保留状态。
下一步是什么?
试着增加一些创意格调,或者新的性能(比方暂停和复原按钮)。之后,如果你想出了任何很酷的时钟例子,你想分享,让咱们在评论区见。
11. 代码
本示例代码和演示地址:https://coding.zhangbing.site