设置有效的结束日期
首先,您需要设置一个有效的结束日期。这应该是 JavaScript 的 Date.parse() 方法可以理解的任何格式的字符串。例如:
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';
计算剩余时间下一步是计算剩余时间。我们需要编写一个函数,它接受一个表示给定结束时间的字符串(如上所述)。然后我们计算该时间与当前时间之间的差异。看起来是这样的:
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
};
}
首先,我们创建一个变量总计,以保留截止日期之前的剩余时间。 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 )
重复此逻辑将毫秒转换为分钟、小时和天。
将时钟数据输出为可重用对象
准备好天、小时、分钟和秒后,我们现在准备将数据作为可重用对象返回:
return {
total,
days,
hours,
minutes,
seconds
};
该对象允许您调用函数并获取任何计算值。以下是如何获取剩余分钟数的示例:
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 以及倒计时的结束时间。在函数内部,我们将声明一个时钟变量并使用它来存储对时钟容器 div 的引用。这意味着我们不必继续查询 DOM。
接下来,我们将使用设置时间间隔每秒执行一个匿名函数。该函数将执行以下操作:
计算剩余时间。
将剩余时间输出到我们的div。
如果剩余时间为零,则停止计时。
此时,唯一剩下的步骤是像这样运行时钟:
initializeClock('clockdiv', deadline);
恭喜!现在,您只需 18 行 JavaScript 就拥有了一个基本时钟。
准备展示时钟在设计时钟之前,我们需要稍微改进一下。
消除初始延迟,以便您的时钟立即显示。
使时钟脚本更加高效,这样它就不会不断重建整个时钟。
根据需要添加前导零。
消除初始延迟在时钟中,我们使用 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(); // 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>
现在让我们获取对这些元素的引用。在定义时钟变量的位置之后添加以下代码
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”,然后切掉最后两位数字。
例如,要向“秒”值添加前导零,您可以更改以下内容:
secondsSpan.innerHTML = t.seconds;
to this:
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
如果您愿意,您也可以在分钟和小时中添加前导零。如果您已经走到这一步,恭喜您!您的时钟现在已准备好显示。
注意:您可能需要单击 CodePen 中的“重新运行”才能开始倒计时。