设置有效的结束日期
首先,您需要设置一个有效的结束日期。这应该是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
};
}
首先,我们创建一个变量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)
重复这个逻辑,将毫秒转换为分钟、小时和天。
将时钟数据输出为可重用对象
准备好天、小时、分钟和秒后,我们现在可以将数据作为可重用对象返回:
return {
total,
days,
hours,
minutes,
seconds
};
这个对象允许您调用函数并获取计算出的任何值。下面是一个示例,展示如何获取剩余分钟数:
getTimeRemaining(deadline).minutes
非常方便,对吧?
...
显示时钟并在达到零时停止
现在我们有了一个可以输出剩余天数、小时、分钟和秒数的函数,我们可以构建我们的时钟。首先,我们将创建以下HTML元素来容纳我们的时钟:
然后,我们将编写一个函数,在新 div 中输出时钟数据:
function initializeClock(id, endtime) {
const clock = document.getElementById(id);
const timeinterval = setInterval(() => {
const t = getTimeRemaining(endtime);
clock.innerHTML = 'days: ' + t.days + '
' +
'hours: '+ t.hours + '
' +
'minutes: ' + t.minutes + '
' +
'seconds: ' + t.seconds;
if (t.total <= 0) {
clearInterval(timeinterval);
}
},1000);
}
该函数接受两个参数,分别是包含我们时钟的元素的id和倒计时的结束时间。在函数内部,我们将声明一个clock变量并使用它来存储对我们的时钟容器div的引用。这意味着我们不必继续查询DOM。
然后,我们将使用setInterval每秒执行一个匿名函数。此函数将执行以下操作:
计算剩余时间。
将剩余时间输出到我们的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 + '
' +
'hours: '+ t.hours + '
' +
'minutes: ' + t.minutes + '
' +
'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代码:
Days:
Hours:
Minutes:
Seconds:
现在让我们引用这些元素。在定义了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”的字符串添加到数字的开头,然后切掉最后两个数字。
例如,要给“秒”值添加前导零,您需要更改以下内容:
secondsSpan.innerHTML = t.seconds;
转化为:
secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);
如果你想的话,你也可以在分钟和小时前面添加前导零。如果你已经完成了这一步,恭喜你!现在你的时钟已经准备好显示了。
注意:你可能需要在CodePen中点击“重新运行”才能开始倒计时。