🎯 案例核心效果

  1. 页面展示可视化倒计时器,支持自定义目标时间(如秒杀结束时间、活动截止时间);
  2. 按「时:分: 秒」格式实时显示剩余时间,数字跳动有视觉反馈,交互体验流畅;
  3. 支持暂停 / 继续、重置倒计时功能,满足不同场景操作需求;
  4. 倒计时结束后给出醒目提示,自动停止计时并重置按钮状态;
  5. 样式简约美观,适配 PC 和移动端,可直接集成到电商秒杀、活动报名等场景。

📌 实现思路(极简清晰)

分 3 步落地,逻辑简单易上手,零基础也能快速掌握:

  1. HTML:搭建倒计时显示区域、功能按钮(暂停 / 继续、重置),结构极简;
  2. CSS:美化倒计时数字、按钮样式,突出结束提示效果,保证视觉层次;
  3. 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标记暂停状态,控制按钮文本切换(暂停 / 继续);
  • 结束状态:禁用暂停按钮,重置按钮文本改为 “重新开始”,提升用户体验;✅ 重置功能
  • 恢复初始目标时间,重置所有状态,支持重新启动倒计时,适配多次使用场景。

💡 新手常见踩坑点(精准避坑,少走弯路)

  1. 倒计时首次更新延迟? → 定时器setInterval首次执行会延迟 1 秒,需在启动时先执行一次updateCountdown()
  2. 暂停后继续计时不准? → 未基于剩余时间重置目标时间,需在继续时重新计算targetTime = new Date(Date.now() + remainingTime)
  3. 时间显示位数错乱? → 未给数字补零,需使用padStart(2, '0')保证两位数,避免出现 “1:5:8” 的不规范显示;
  4. 结束后按钮状态未更新? → 未禁用暂停按钮、修改重置按钮文本,需在结束逻辑中处理按钮状态;
  5. 目标时间设置错误? → 直接使用固定时间戳导致跨天 / 跨时区错误,推荐基于当前时间 + 时长的方式设置(如示例)。

🔧 扩展思路(落地性强,新手可练)

  1. 自定义目标时间:添加输入框,支持用户手动输入结束时间(如 “2026-03-20 20:00:00”),适配不同活动场景;
  2. 毫秒级倒计时:扩展显示毫秒数,适配秒杀等高精准度场景;
  3. 样式自定义:添加颜色选择器,支持自定义倒计时数字、按钮的颜色,适配不同页面风格;
  4. 声音提醒:倒计时结束时播放提示音,提升场景适配性(如活动开始提醒);
  5. 多时段倒计时:支持添加多个倒计时(如 “秒杀 1”“秒杀 2”),切换显示,适配多活动场景;
  6. 本地存储:将倒计时状态保存到 localStorage,页面刷新后恢复计时,提升用户体验。

🎯 核心知识点总结(凝练精准,实战导向)

  1. 时间处理:掌握Date对象的使用,计算时间差、格式化时间,适配倒计时核心逻辑;
  2. 定时器控制setInterval()/clearInterval()实现定时更新,解决暂停 / 继续 / 重置的状态管理;
  3. 字符串处理padStart()补零操作,保证时间格式统一,提升视觉体验;
  4. 状态管理:通过布尔值标记暂停状态,动态更新按钮文本和禁用状态,实现完整交互;
  5. 边界处理:判断倒计时结束状态,及时停止定时器并更新 UI,避免负时间显示;
  6. 交互设计:按钮功能分区、状态反馈清晰,适配秒杀 / 活动等实战场景的操作需求。

📢 互动留言

跟着案例实操一遍,轻松实现秒杀 / 活动场景的倒计时器!这个功能在电商秒杀、活动报名、考试计时等场景中高频使用,复制代码就能直接复用。如果遇到计时不准、暂停后继续出错等问题,评论区留言,我会第一时间解答;你还想给倒计时器添加哪些扩展(比如毫秒级显示、声音提醒),也可以留言告诉我~

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐