【JS 实战案例】用 JS 实现一个简单的倒计时器(秒杀 / 活动场景)
本文手把手实现一个实用的 JS 倒计时器,适配秒杀 / 活动等实战场景,支持暂停 / 继续、重置、结束提示等核心功能,按「时:分: 秒」格式精准显示剩余时间。代码精简可复用,重点拆解时间计算、定时器控制、状态管理等核心知识点,无冗余内容,贴合 CSDN 高分行文逻辑,助力前端零基础新手快速掌握这个高频实用的时间交互技巧。
·
🎯 案例核心效果
- 页面展示可视化倒计时器,支持自定义目标时间(如秒杀结束时间、活动截止时间);
- 按「时:分: 秒」格式实时显示剩余时间,数字跳动有视觉反馈,交互体验流畅;
- 支持暂停 / 继续、重置倒计时功能,满足不同场景操作需求;
- 倒计时结束后给出醒目提示,自动停止计时并重置按钮状态;
- 样式简约美观,适配 PC 和移动端,可直接集成到电商秒杀、活动报名等场景。

📌 实现思路(极简清晰)
分 3 步落地,逻辑简单易上手,零基础也能快速掌握:
- HTML:搭建倒计时显示区域、功能按钮(暂停 / 继续、重置),结构极简;
- CSS:美化倒计时数字、按钮样式,突出结束提示效果,保证视觉层次;
- JS:定义目标时间→计算剩余时间→格式化时间显示→定时器更新倒计时→绑定按钮交互事件。
🚀 完整源码(可直接复制运行)
html
预览
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JS 简单倒计时器 | 秒杀/活动场景</title>
<style>
/* 全局重置(精简规范) */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: "Microsoft YaHei", sans-serif;
}
/* 页面布局:居中显示 */
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 20px;
background-color: #f5f5f5;
}
/* 标题样式 */
.title {
font-size: 24px;
color: #333;
margin-bottom: 30px;
text-align: center;
}
/* 倒计时容器 */
.countdown-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 25px;
width: 100%;
max-width: 500px;
padding: 30px;
background-color: #fff;
border-radius: 12px;
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.05);
}
/* 倒计时数字区域 */
.countdown-display {
display: flex;
align-items: center;
gap: 15px;
font-size: 0; /* 消除inline-block间隙 */
}
/* 时间项(时/分/秒) */
.time-item {
display: inline-block;
width: 80px;
height: 80px;
line-height: 80px;
text-align: center;
font-size: 32px;
font-weight: bold;
color: #fff;
background-color: #409eff;
border-radius: 8px;
}
/* 分隔符 */
.separator {
font-size: 32px;
color: #333;
font-weight: bold;
}
/* 功能按钮组 */
.btn-group {
display: flex;
gap: 15px;
}
/* 按钮样式 */
.countdown-btn {
padding: 10px 24px;
font-size: 16px;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
}
.pause-btn {
background-color: #e6a23c;
color: #fff;
}
.pause-btn:hover {
background-color: #f0b568;
}
.reset-btn {
background-color: #f56c6c;
color: #fff;
}
.reset-btn:hover {
background-color: #f88888;
}
/* 结束提示 */
.end-tip {
font-size: 20px;
color: #f56c6c;
font-weight: bold;
display: none;
}
/* 禁用状态按钮 */
.countdown-btn:disabled {
background-color: #ccc;
cursor: not-allowed;
}
/* 移动端适配 */
@media (max-width: 500px) {
.title {
font-size: 20px;
}
.time-item {
width: 60px;
height: 60px;
line-height: 60px;
font-size: 24px;
}
.separator {
font-size: 24px;
}
.countdown-btn {
padding: 8px 18px;
font-size: 14px;
}
}
</style>
</head>
<body>
<h1 class="title">秒杀/活动倒计时器</h1>
<div class="countdown-container">
<!-- 倒计时显示 -->
<div class="countdown-display">
<div class="time-item" id="hours">00</div>
<span class="separator">:</span>
<div class="time-item" id="minutes">00</div>
<span class="separator">:</span>
<div class="time-item" id="seconds">00</div>
</div>
<!-- 结束提示 -->
<div class="end-tip" id="endTip">倒计时结束!</div>
<!-- 功能按钮 -->
<div class="btn-group">
<button class="countdown-btn pause-btn" id="pauseBtn">暂停</button>
<button class="countdown-btn reset-btn" id="resetBtn">重置</button>
</div>
</div>
<script>
// 1. 获取DOM元素
const hoursEl = document.getElementById('hours');
const minutesEl = document.getElementById('minutes');
const secondsEl = document.getElementById('seconds');
const pauseBtn = document.getElementById('pauseBtn');
const resetBtn = document.getElementById('resetBtn');
const endTip = document.getElementById('endTip');
// 2. 核心配置(可自定义目标时间)
// 示例:设置1小时30分钟后结束(可替换为具体日期,如new Date('2026-03-20 20:00:00'))
const targetTime = new Date(Date.now() + 1 * 60 * 60 * 1000 + 30 * 60 * 1000);
let countdownTimer; // 倒计时定时器
let isPaused = false; // 暂停状态标记
let remainingTime = 0; // 剩余时间(毫秒)
// 3. 格式化时间:将毫秒转换为 时:分:秒
function formatTime(ms) {
// 计算小时、分钟、秒
const hours = Math.floor(ms / (1000 * 60 * 60));
const minutes = Math.floor((ms % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((ms % (1000 * 60)) / 1000);
// 补零(保证两位数显示)
return {
hours: hours.toString().padStart(2, '0'),
minutes: minutes.toString().padStart(2, '0'),
seconds: seconds.toString().padStart(2, '0')
};
}
// 4. 更新倒计时显示
function updateCountdown() {
// 计算剩余时间
remainingTime = targetTime - Date.now();
// 倒计时结束判断
if (remainingTime <= 0) {
clearInterval(countdownTimer);
// 显示结束提示
endTip.style.display = 'block';
// 更新为00:00:00
hoursEl.textContent = '00';
minutesEl.textContent = '00';
secondsEl.textContent = '00';
// 禁用按钮
pauseBtn.disabled = true;
resetBtn.textContent = '重新开始';
return;
}
// 格式化时间并更新DOM
const { hours, minutes, seconds } = formatTime(remainingTime);
hoursEl.textContent = hours;
minutesEl.textContent = minutes;
secondsEl.textContent = seconds;
}
// 5. 启动倒计时
function startCountdown() {
// 先执行一次,避免延迟
updateCountdown();
// 启动定时器(每秒更新一次)
countdownTimer = setInterval(updateCountdown, 1000);
}
// 6. 绑定暂停/继续按钮事件
pauseBtn.addEventListener('click', () => {
if (isPaused) {
// 继续倒计时:重置目标时间(基于剩余时间)
targetTime = new Date(Date.now() + remainingTime);
startCountdown();
pauseBtn.textContent = '暂停';
isPaused = false;
} else {
// 暂停倒计时
clearInterval(countdownTimer);
pauseBtn.textContent = '继续';
isPaused = true;
}
});
// 7. 绑定重置按钮事件
resetBtn.addEventListener('click', () => {
// 清除定时器
clearInterval(countdownTimer);
// 重置目标时间(恢复初始配置)
targetTime = new Date(Date.now() + 1 * 60 * 60 * 1000 + 30 * 60 * 1000);
// 重置状态
isPaused = false;
endTip.style.display = 'none';
pauseBtn.textContent = '暂停';
pauseBtn.disabled = false;
resetBtn.textContent = '重置';
// 重新启动
startCountdown();
});
// 初始化:启动倒计时
startCountdown();
</script>
</body>
</html>
📖 核心代码拆解(重点突出,易懂好记)
1. HTML 结构(极简规整)
核心分为 3 部分,功能边界清晰:
countdown-display:倒计时数字展示区域,按「时:分: 秒」布局,分隔符增强可读性;end-tip:倒计时结束提示,默认隐藏,结束后显示;btn-group:功能按钮组,包含暂停 / 继续、重置按钮,适配不同操作需求。
2. CSS 样式(简约美观,交互友好)
重点关注 3 个核心样式:
- 数字样式:时间项使用固定宽高、居中对齐,背景色突出显示,提升视觉辨识度;
- 状态反馈:按钮区分不同颜色(暂停 - 黄色、重置 - 红色),禁用状态灰显,交互感知清晰;
- 响应式适配:移动端缩小数字和按钮尺寸,保证显示效果一致,无布局错乱。
3. JS 逻辑(核心中的核心,分步拆解)
✅ 时间计算:
formatTime():将毫秒数转换为「时:分: 秒」格式,通过padStart(2, '0')补零,保证两位数显示;- 剩余时间计算:
targetTime - Date.now(),精准获取距离目标时间的毫秒数;
✅ 倒计时控制:
startCountdown():启动定时器,每秒更新一次倒计时,先执行一次避免首次延迟;- 暂停逻辑:清除定时器,记录剩余时间;继续逻辑:基于剩余时间重置目标时间,保证计时准确;
✅ 状态管理:
isPaused标记暂停状态,控制按钮文本切换(暂停 / 继续);- 结束状态:禁用暂停按钮,重置按钮文本改为 “重新开始”,提升用户体验;✅ 重置功能:
- 恢复初始目标时间,重置所有状态,支持重新启动倒计时,适配多次使用场景。
💡 新手常见踩坑点(精准避坑,少走弯路)
- 倒计时首次更新延迟? → 定时器
setInterval首次执行会延迟 1 秒,需在启动时先执行一次updateCountdown(); - 暂停后继续计时不准? → 未基于剩余时间重置目标时间,需在继续时重新计算
targetTime = new Date(Date.now() + remainingTime); - 时间显示位数错乱? → 未给数字补零,需使用
padStart(2, '0')保证两位数,避免出现 “1:5:8” 的不规范显示; - 结束后按钮状态未更新? → 未禁用暂停按钮、修改重置按钮文本,需在结束逻辑中处理按钮状态;
- 目标时间设置错误? → 直接使用固定时间戳导致跨天 / 跨时区错误,推荐基于当前时间 + 时长的方式设置(如示例)。
🔧 扩展思路(落地性强,新手可练)
- 自定义目标时间:添加输入框,支持用户手动输入结束时间(如 “2026-03-20 20:00:00”),适配不同活动场景;
- 毫秒级倒计时:扩展显示毫秒数,适配秒杀等高精准度场景;
- 样式自定义:添加颜色选择器,支持自定义倒计时数字、按钮的颜色,适配不同页面风格;
- 声音提醒:倒计时结束时播放提示音,提升场景适配性(如活动开始提醒);
- 多时段倒计时:支持添加多个倒计时(如 “秒杀 1”“秒杀 2”),切换显示,适配多活动场景;
- 本地存储:将倒计时状态保存到 localStorage,页面刷新后恢复计时,提升用户体验。
🎯 核心知识点总结(凝练精准,实战导向)
- 时间处理:掌握
Date对象的使用,计算时间差、格式化时间,适配倒计时核心逻辑; - 定时器控制:
setInterval()/clearInterval()实现定时更新,解决暂停 / 继续 / 重置的状态管理; - 字符串处理:
padStart()补零操作,保证时间格式统一,提升视觉体验; - 状态管理:通过布尔值标记暂停状态,动态更新按钮文本和禁用状态,实现完整交互;
- 边界处理:判断倒计时结束状态,及时停止定时器并更新 UI,避免负时间显示;
- 交互设计:按钮功能分区、状态反馈清晰,适配秒杀 / 活动等实战场景的操作需求。
📢 互动留言
跟着案例实操一遍,轻松实现秒杀 / 活动场景的倒计时器!这个功能在电商秒杀、活动报名、考试计时等场景中高频使用,复制代码就能直接复用。如果遇到计时不准、暂停后继续出错等问题,评论区留言,我会第一时间解答;你还想给倒计时器添加哪些扩展(比如毫秒级显示、声音提醒),也可以留言告诉我~
更多推荐
所有评论(0)