在Web开发中,很多场景需要用到倒计时功能,比如活动开始倒计时、验证码有效期倒计时等。如果仅用变量在内存中保存倒计时状态,页面刷新后变量会被重置,导致倒计时从头开始,影响用户体验。要实现倒计时持久化,核心是将倒计时的关键状态存储到浏览器本地,页面加载时读取存储的状态恢复倒计时。

基础倒计时实现逻辑
首先我们先实现一个基础的、不持久化的倒计时功能,核心是通过定时器每秒更新剩余时间,当剩余时间归零时清除定时器。
// 基础倒计时示例,不持久化
let remainingTime = 60; // 剩余时间,单位秒
const countdownElement = document.getElementById('countdown');
function updateCountdown() {
if (remainingTime <= 0) {
countdownElement.textContent = '倒计时结束';
clearInterval(timer);
return;
}
countdownElement.textContent = `剩余${remainingTime}秒`;
remainingTime--;
}
// 初始更新一次
updateCountdown();
// 每秒执行一次更新
const timer = setInterval(updateCountdown, 1000);
利用localStorage实现持久化
localStorage是浏览器提供的本地存储API,数据会保存在浏览器中,除非主动清除,否则关闭页面、刷新页面都不会丢失。我们可以用它存储倒计时的两个关键信息:倒计时的总时长、倒计时开始的时间戳。
存储逻辑设计
我们不需要每秒都存储剩余时间,只需要存储倒计时开始的时间点和总时长,页面刷新后通过当前时间减去开始时间,就能计算出真实的剩余时间,减少存储操作的频率。
- 倒计时开始时,将开始时间戳
startTime和总时长totalTime存入localStorage - 页面加载时,先读取localStorage中的这两个值,计算剩余时间
- 倒计时结束后,清除localStorage中的存储数据
完整持久化倒计时实现
// 获取显示倒计时的DOM元素
const countdownElement = document.getElementById('countdown');
// localStorage的存储键名
const STORAGE_KEY_START = 'countdown_start_time';
const STORAGE_KEY_TOTAL = 'countdown_total_time';
// 初始化倒计时
function initCountdown() {
// 先从localStorage读取存储的数据
const storedStartTime = localStorage.getItem(STORAGE_KEY_START);
const storedTotalTime = localStorage.getItem(STORAGE_KEY_TOTAL);
let startTime, totalTime;
if (storedStartTime && storedTotalTime) {
// 如果本地有存储数据,使用存储的数据
startTime = Number(storedStartTime);
totalTime = Number(storedTotalTime);
} else {
// 没有存储数据,说明是第一次启动倒计时,设置初始值
totalTime = 60; // 总时长60秒
startTime = Date.now(); // 当前时间戳作为开始时间
// 存入localStorage
localStorage.setItem(STORAGE_KEY_START, startTime);
localStorage.setItem(STORAGE_KEY_TOTAL, totalTime);
}
// 计算剩余时间
function calculateRemaining() {
const currentTime = Date.now();
// 已经过去的时间(毫秒转秒)
const elapsedSeconds = Math.floor((currentTime - startTime) / 1000);
// 剩余时间 = 总时长 - 已过去时间
let remaining = totalTime - elapsedSeconds;
// 剩余时间不能小于0
if (remaining < 0) remaining = 0;
return remaining;
}
// 更新倒计时显示
function updateCountdown() {
const remaining = calculateRemaining();
if (remaining <= 0) {
countdownElement.textContent = '倒计时结束';
// 清除定时器
clearInterval(timer);
// 清除localStorage存储的数据
localStorage.removeItem(STORAGE_KEY_START);
localStorage.removeItem(STORAGE_KEY_TOTAL);
return;
}
// 格式化显示,时分秒格式
const hours = Math.floor(remaining / 3600);
const minutes = Math.floor((remaining % 3600) / 60);
const seconds = remaining % 60;
let displayText = '';
if (hours > 0) displayText += `${hours}时`;
if (minutes > 0) displayText += `${minutes}分`;
displayText += `${seconds}秒`;
countdownElement.textContent = `剩余${displayText}`;
}
// 初始更新一次
updateCountdown();
// 每秒更新一次
const timer = setInterval(updateCountdown, 1000);
}
// 页面加载完成后初始化倒计时
window.addEventListener('DOMContentLoaded', initCountdown);
注意事项
在使用localStorage实现倒计时持久化时,需要注意以下几点:
- localStorage只能存储字符串,所以存储数字类型的时间戳时需要转成字符串,读取时再转成数字
- 如果用户手动修改了本地时间,可能会导致倒计时计算出现偏差,若对精度要求极高,可以结合服务器时间校准
- 当倒计时结束后,一定要及时清除localStorage中的存储数据,避免下次进入页面时读取到旧数据
- 如果用户同时打开多个标签页,多个标签页的倒计时会共享localStorage中的数据,可能会出现状态冲突,若需要隔离不同标签页的倒计时,可以结合标签页唯一标识存储
扩展:使用sessionStorage的场景
如果希望倒计时仅在当前浏览器标签页有效,关闭标签页后重置,可以将localStorage替换为sessionStorage,sessionStorage的生命周期和标签页一致,关闭标签页后数据会自动清除,其他实现逻辑和localStorage完全一致。
// 仅需将localStorage替换为sessionStorage即可 // 存储数据 sessionStorage.setItem(STORAGE_KEY_START, startTime); sessionStorage.setItem(STORAGE_KEY_TOTAL, totalTime); // 读取数据 const storedStartTime = sessionStorage.getItem(STORAGE_KEY_START); const storedTotalTime = sessionStorage.getItem(STORAGE_KEY_TOTAL); // 清除数据 sessionStorage.removeItem(STORAGE_KEY_START); sessionStorage.removeItem(STORAGE_KEY_TOTAL);
JavaScript倒计时localStorage持久化页面刷新修改时间:2026-06-27 07:48:29