摘要:在本教程中,您将学习如何开发可复用的 JavaScript 倒计时器。
什么是倒计时器
倒计时器是运行在登录页面上的虚拟时钟。它从某个日期开始倒计时,以指示事件的开始(或结束)。
在电子商务网站上,您可以使用倒计时器来显示优惠的开始(或结束)。倒计时的目的是敦促客户采取行动,例如购买产品或服务。
在本教程中,您将学习如何从头开始在 JavaScript 中创建倒计时器。您还将学习如何使用它来构建新年倒计时器。
以下是最终的新年倒计时登录页面:https://javascripttutorial.net/sample/dom/countdown-timer/
请注意,您将要构建的倒计时器是可复用的,因此您可以在任何登录页面上使用它。此外,您还可以使用此倒计时在单个页面上创建多个倒计时器。
创建项目结构
首先,创建一个名为 countdown-timer
的项目文件夹。在这个文件夹中,创建三个子文件夹:js
、css
和 img
,分别用来存储 JavaScript、CSS 和图像文件。
其次,在 css
文件夹中创建 style.css
,在 js
文件夹中创建 app.js
和 countdown.js
文件,并在 countdown-timer
文件夹中创建 index.html
。
第三,下载此烟花图片 并将其复制到 img
文件夹中。您将使用此图片作为新年倒计时页面的背景。
项目结构如下所示

创建 HTML 页面
HTML 页面非常简单,因为您将从 JavaScript 生成大部分 HTML 代码。
以下是完整的 HTML 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript Countdown Timer - New Year Countdown</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>New Year Countdown</h1>
<div class="countdown-timer"></div>
<div class="message"></div>
<div class="year"></div>
<script src="js/countdown.js"></script>
<script src="js/app.js"></script>
</body>
</html>
Code language: HTML, XML (xml)
在 index.html
文件中,您将 style.css
文件的链接放在 <head>
部分,将 countdown.js
和 app.js
文件放在 <body>
部分。
请注意,countdown.js
文件必须出现在 app.js
文件之前,因为 app.js
将使用 countdown.js
文件中的对象。
<body>
部分有四个元素
- 一个标题 1 (
<h1>
)。此元素将显示标题。它可以是描述倒计时的任何内容,例如:新年倒计时。 - 一个具有
countdown-timer
类的<div>
。此元素将显示倒计时。 - 一个具有
message
类的<div>
。此元素将在倒计时完成时显示消息。 - 以及一个具有
year
类的<div>
。此元素将显示新年,例如:2021。
Date 对象的快速概述
要创建计时器,您需要使用 Date
对象,该对象在所有 Web 浏览器中都可用。
Date
对象表示时间中的一个特定时刻。它包含一个数字,表示自 1970 年 1 月 1 日 UTC 以来经过的毫秒数。
以下是如何创建一个表示当前日期和时间的新 Date
对象
const now = new Date();
Code language: JavaScript (javascript)
此示例显示了如何调用 Date
对象的 getTime()
方法来获取自 1970 年 1 月 1 日 00:00:00 UTC
以来经过的毫秒数
const time = now.getTime();
console.log(time);
Code language: JavaScript (javascript)
要使用指定的日期和时间创建一个新的 Date
对象,您可以将日期字符串传递到 Date()
构造函数中,如下所示
const d = new Date('February 02, 2020 01:02:03');
console.log(d.getTime()); // 1580580123000
Code language: JavaScript (javascript)
要计算两次时间之间的毫秒数,您可以调用 getTime()
方法并使用 -
运算符。例如
const d1 = new Date('September 17, 2020 00:00:00');
const d2 = new Date('September 19, 2020 01:00:00');
const time = d2.getTime() - d1.getTime();
console.log(time); // 176400000
Code language: JavaScript (javascript)
计算剩余时间
倒计时器需要计算自某个毫秒数以来的剩余天数、小时、分钟和秒数,并将此信息显示在网页上。
以下声明了一个名为 time
的变量,其值为 150000 毫秒
const time = 150000; // ms
Code language: JavaScript (javascript)
要将毫秒转换为分钟,您可以将毫秒除以 1000 以获得秒数,然后将秒数除以 60 以获得分钟数。例如
console.log(time / 1000 / 60);
Code language: JavaScript (javascript)
输出
2.5
Code language: CSS (css)
要获取剩余分钟数 (2),您可以使用 Math.floor()
函数
const minutes = Math.floor(time / 1000 / 60);
console.log(minutes); // 2
Code language: JavaScript (javascript)
要获取剩余秒数 (30),您可以使用模运算符 ( % ),它返回除法的余数
const seconds = Math.floor(time / 1000) % 60;
console.log(seconds); // 30
Code language: JavaScript (javascript)
开发 CountDown 类
首先,在 countdown.js
文件中创建一个新的 CountDown
类
class CountDown {
}
Code language: JavaScript (javascript)
CountDown
类应使用三个参数进行初始化
- 一个过期日期。
- 一个负责呈现倒计时器的回调函数。
- 以及另一个在倒计时完成时将被调用的回调函数。
CountDown
类的构造函数将如下所示
class CountDown {
constructor(expiredDate, onRender, onComplete) {
this.onRender = onRender;
this.onComplete = onComplete;
// handle the expired Date
..
}
}
Code language: JavaScript (javascript)
根据 expiredDate
参数,您可以计算剩余时间(以毫秒为单位)
const currentTime = new Date().getTime();
const timeRemaining = expiredDate.getTime() - currentTime;
Code language: JavaScript (javascript)
由于您需要在类的所有方法中访问剩余时间 (timeRemaining
),因此应将其定义为 CountDown
类的属性。
setExpiredDate() 方法
以下定义了一个名为 setExpiredDate()
的新方法,它初始化 timeRemaining
属性
setExpiredDate(expiredDate) {
// get the current time
const currentTime = new Date().getTime();
// calculate the remaining time
this.timeRemaining = expiredDate.getTime() - currentTime;
}
Code language: JavaScript (javascript)
如果 timeRemaining
大于零,setExpiredDate()
方法将执行 start()
方法来启动计时器。否则,它将执行 complete()
方法。
setExpiredDate()
将如下所示
setExpiredDate(expiredDate) {
// get the current time
const currentTime = new Date().getTime();
// calculate the remaining time
this.timeRemaining = expiredDate.getTime() - currentTime;
// should the countdown completes or start
this.timeRemaining > 0 ?
this.start() :
this.complete();
}
Code language: JavaScript (javascript)
请注意,我们使用了 三元运算符 ?:
根据 this.timeRemaining
属性的值来执行 complete()
或 start()
方法。
complete() 方法
complete()
方法检查 onComplete
回调是否已传递,并调用它。如果 onComplete
不可用,complete()
不会执行任何操作。
complete() {
if (typeof this.onComplete === 'function') {
onComplete();
}
}
Code language: JavaScript (javascript)
start() 方法
start()
方法每秒 (1000 毫秒) 减少 timeRemaining
属性一次。
如果剩余时间小于零,start()
方法将
- 首先,调用
complete()
方法。 - 其次,使用
clearInterval()
函数清除计时器。
start() {
// setup a timer
const intervalId = setInterval(() => {
// update the timer
this.timeRemaining -= 1000;
if (this.timeRemaining < 0) {
// call the callback
complete();
// clear the interval if expired
clearInterval(intervalId);
}
}, 1000);
}
Code language: JavaScript (javascript)
如果剩余时间大于零,start()
方法应调用一个方法来执行 onRender
回调函数。
getTime() 方法
以下 getTime()
方法返回一个对象,该对象包含根据 timeRemaining
属性计算出的剩余天数、小时、分钟和秒数。
getTime() {
return {
days: Math.floor(this.timeRemaining / 1000 / 60 / 60 / 24),
hours: Math.floor(this.timeRemaining / 1000 / 60 / 60) % 24,
minutes: Math.floor(this.timeRemaining / 1000 / 60) % 60,
seconds: Math.floor(this.timeRemaining / 1000) % 60
};
}
Code language: JavaScript (javascript)
update() 方法
以下定义了 update()
方法,该方法使用 getTime()
方法返回的当前剩余时间对象来调用 onRender()
回调函数
update() {
if (typeof this.onRender === 'function') {
this.onRender(this.getTime());
}
}
Code language: JavaScript (javascript)
start()
方法将在开始时以及之后的每秒调用 update()
方法
start() {
// update the countdown
this.update();
// setup a timer
const intervalId = setInterval(() => {
// update the timer
this.timeRemaining -= 1000;
if (this.timeRemaining < 0) {
// call the callback
complete();
// clear the interval if expired
clearInterval(intervalId);
} else {
this.update();
}
}, 1000);
}
Code language: JavaScript (javascript)
以下是完整的 CountDown
类
class CountDown {
constructor(expiredDate, onRender, onComplete) {
this.setExpiredDate(expiredDate);
this.onRender = onRender;
this.onComplete = onComplete;
}
setExpiredDate(expiredDate) {
// get the current time
const currentTime = new Date().getTime();
// calculate the remaining time
this.timeRemaining = expiredDate.getTime() - currentTime;
this.timeRemaining <= 0 ?
this.complete() :
this.start();
}
complete() {
if (typeof this.onComplete === 'function') {
onComplete();
}
}
getTime() {
return {
days: Math.floor(this.timeRemaining / 1000 / 60 / 60 / 24),
hours: Math.floor(this.timeRemaining / 1000 / 60 / 60) % 24,
minutes: Math.floor(this.timeRemaining / 1000 / 60) % 60,
seconds: Math.floor(this.timeRemaining / 1000) % 60
};
}
update() {
if (typeof this.onRender === 'function') {
this.onRender(this.getTime());
}
}
start() {
// update the countdown
this.update();
// setup a timer
const intervalId = setInterval(() => {
// update the timer
this.timeRemaining -= 1000;
if (this.timeRemaining < 0) {
// call the callback
complete();
// clear the interval if expired
clearInterval(intervalId);
} else {
this.update();
}
}, 1000);
}
}
Code language: JavaScript (javascript)
构建新年倒计时
首先,创建一个名为 getNewYear()
的新函数,该函数返回新年
const getNewYear = () => {
const currentYear = new Date().getFullYear();
return new Date(`January 01 ${currentYear + 1} 00:00:00`);
};
Code language: JavaScript (javascript)
其次,选择并更新 .year
元素。它将显示新年的四位数年份数字,例如:2021
// update the year element
const year = document.querySelector('.year');
year.innerHTML = getNewYear().getFullYear();
Code language: JavaScript (javascript)
第三,选择 .countdown-timer
、.message
和 h1
元素
// select elements
const app = document.querySelector('.countdown-timer');
const message = document.querySelector('.message');
const heading = document.querySelector('h1');
Code language: JavaScript (javascript)
第四,定义一个格式化函数,如果数字小于 10,则用 '0'
填充数字。例如,5 将变为 05
。但 10 将保持不变。
const format = (t) => {
return t < 10 ? '0' + t : t;
};
Code language: JavaScript (javascript)
第五,定义一个 render()
方法,该方法从时间对象中组合 HTML 标记并将其更新到 .countdown-timer
元素中。它将显示剩余的天数、小时、分钟和秒数。
const render = (time) => {
app.innerHTML = `
<div class="count-down">
<div class="timer">
<h2 class="days">${format(time.days)}</h2>
<small>Days</small>
</div>
<div class="timer">
<h2 class="hours">${format(time.hours)}</h2>
<small>Hours</small>
</div>
<div class="timer">
<h2 class="minutes">${format(time.minutes)}</h2>
<small>Minutes</small>
</div>
<div class="timer">
<h2 class="seconds">${format(time.seconds)}</h2>
<small>Seconds</small>
</div>
</div>
`;
};
Code language: HTML, XML (xml)
第五,倒计时完成后,它将显示一条消息,例如:"新年快乐"
。
以下 showMessage()
函数显示 新年快乐
消息。此外,它还清除 .countdown-timer
元素的内容并隐藏标题元素
const showMessage = () => {
message.innerHTML = `Happy New Year ${newYear}!`;
app.innerHTML = '';
heading.style.display = 'none';
};
Code language: JavaScript (javascript)
第六,新年倒计时应在一段时间内显示新年快乐的祝贺消息,然后再次显示新年倒计时。
以下定义了一个函数,用于隐藏祝贺消息并显示标题元素
const hideMessage = () => {
message.innerHTML = '';
heading.style.display = 'block';
}
Code language: JavaScript (javascript)
第七,定义一个 complete()
函数,该函数在一段时间内显示消息,然后将其隐藏。此外,它还将 expiredDate
设置为新年
const complete = () => {
showMessage();
// restart the countdown after showing the
// greeting message for a day ()
setTimeout(() => {
hideMessage();
countdownTimer.setExpiredDate(getNewYear());
}, 1000 * 60 * 24);
};
Code language: JavaScript (javascript)
最后,创建新的 CountDown
实例,并将新年日期、render
函数和 complete
函数传递到其构造函数中
const countdownTimer = new CountDown(
getNewYear(),
render,
complete
);
Code language: JavaScript (javascript)
以下是完整的 app.js
文件
// Get the new year
const getNewYear = () => {
const currentYear = new Date().getFullYear();
return new Date(`January 01 ${currentYear + 1} 00:00:00`);
};
// update the year element
const year = document.querySelector('.year');
year.innerHTML = getNewYear().getFullYear();
// select elements
const app = document.querySelector('.countdown-timer');
const message = document.querySelector('.message');
const heading = document.querySelector('h1');
const format = (t) => {
return t < 10 ? '0' + t : t;
};
const render = (time) => {
app.innerHTML = `
<div class="count-down">
<div class="timer">
<h2 class="days">${format(time.days)}</h2>
<small>Days</small>
</div>
<div class="timer">
<h2 class="hours">${format(time.hours)}</h2>
<small>Hours</small>
</div>
<div class="timer">
<h2 class="minutes">${format(time.minutes)}</h2>
<small>Minutes</small>
</div>
<div class="timer">
<h2 class="seconds">${format(time.seconds)}</h2>
<small>Seconds</small>
</div>
</div>
`;
};
const showMessage = () => {
message.innerHTML = `Happy New Year ${newYear}!`;
app.innerHTML = '';
heading.style.display = 'none';
};
const hideMessage = () => {
message.innerHTML = '';
heading.style.display = 'block';
};
const complete = () => {
showMessage();
// restart the countdown after showing the
// greeting message for a day ()
setTimeout(() => {
hideMessage();
countdownTimer.setExpiredDate(getNewYear());
}, 1000 * 60 * 60 * 24);
};
const countdownTimer = new CountDown(
getNewYear(),
render,
complete
);
Code language: JavaScript (javascript)
如果您打开 index.html
,您会看到新年倒计时已经启动并运行:https://tutorial.javascript.ac.cn/sample/dom/countdown-timer/
总结
在本教程中,您学习了如何
- 使用 ES6 类 来定义可复用的倒计时器组件。
- 使用
Date
对象来操作时间。 - 使用
setInterval()
和clearInterval()
来创建和取消定时重复操作。