JS LocalStorage计时器部署后失效,数值停留在200天
问题:LocalStorage存储的计时器部署后卡在200天,本地运行正常
我编写了一段使用LocalStorage存储的计时器代码,旨在实现关闭标签页后仍能持续计时的功能。该代码在本地运行完全正常,但部署到服务器后,计时器的数值却卡在了200天。移除以下LocalStorage相关代码后,部署版本可正常运行,但页面刷新时计时器会被重置:
var time= localStorage.getItem('saved_timer'); if(time == null) { localStorage.setItem('saved_timer', saved_timer); const saved_timer = (deadline); time = saved_timer; } deadline=time;
我在其他页面使用LocalStorage的功能均运行正常。完整代码如下:
function getTimeRemaining(endtime) { var t = Date.parse(endtime) - Date.parse(new Date()); var seconds = Math.floor((t / 1000) % 60); var minutes = Math.floor((t / 1000 / 60) % 60); var hours = Math.floor((t / (1000 * 60 * 60)) % 24); var days = Math.floor(t / (1000 * 60 * 60 * 24)); return { 'total': t, 'days': days, 'hours': hours, 'minutes': minutes, 'seconds': seconds }; } function initializeClock(id, endtime) { var clock = document.getElementById(id); var daysSpan = clock.querySelector('.days'); var hoursSpan = clock.querySelector('.hours'); var minutesSpan = clock.querySelector('.minutes'); var secondsSpan = clock.querySelector('.seconds'); function updateClock() { var t = getTimeRemaining(endtime); daysSpan.innerHTML = t.days; hoursSpan.innerHTML = ('0' + t.hours).slice(-2); minutesSpan.innerHTML = ('0' + t.minutes).slice(-2); secondsSpan.innerHTML = ('0' + t.seconds).slice(-2); if (t.total <= 0) { clearInterval(timeinterval); } } updateClock(); var timeinterval = setInterval(updateClock, 1000); } var deadline = new Date(Date.parse(new Date()) + 30 * 24 * 60 * 60 * 1000); var time= localStorage.getItem('saved_timer'); if(time == null) { localStorage.setItem('saved_timer', saved_timer); const saved_timer = (deadline); time = saved_timer; } deadline=time; initializeClock('clockdiv', deadline);
问题原因与修复方案
核心问题分析
- 变量声明顺序错误:调用
localStorage.setItem('saved_timer', saved_timer)时,saved_timer还未被声明,本地宽松模式可能未抛出错误,但服务器环境会导致该变量未定义,进而向LocalStorage存储了undefined值。 - Date对象存储解析不一致:直接将Date对象存入LocalStorage会被自动转为字符串,不同环境下的字符串格式可能存在差异,导致
Date.parse(endtime)解析失败,返回无效时间戳,计算出的剩余时间异常(表现为200天左右)。
修复后代码实现
关键逻辑修正
// 处理LocalStorage存储逻辑 var savedTime = localStorage.getItem('saved_timer'); var deadline; if (savedTime === null) { // 首次访问,设置30天后的截止时间 deadline = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); // 存储时间戳而非Date对象,避免解析问题 localStorage.setItem('saved_timer', deadline.getTime()); } else { // 读取时间戳并转为Date对象 deadline = new Date(parseInt(savedTime)); } initializeClock('clockdiv', deadline);
完整修复代码
function getTimeRemaining(endtime) { // 直接使用Date对象的getTime()方法,避免解析错误 var t = endtime.getTime() - Date.now(); var seconds = Math.floor((t / 1000) % 60); var minutes = Math.floor((t / 1000 / 60) % 60); var hours = Math.floor((t / (1000 * 60 * 60)) % 24); var days = Math.floor(t / (1000 * 60 * 60 * 24)); return { 'total': t, 'days': days, 'hours': hours, 'minutes': minutes, 'seconds': seconds }; } function initializeClock(id, endtime) { var clock = document.getElementById(id); var daysSpan = clock.querySelector('.days'); var hoursSpan = clock.querySelector('.hours'); var minutesSpan = clock.querySelector('.minutes'); var secondsSpan = clock.querySelector('.seconds'); function updateClock() { var t = getTimeRemaining(endtime); daysSpan.innerHTML = t.days; hoursSpan.innerHTML = ('0' + t.hours).slice(-2); minutesSpan.innerHTML = ('0' + t.minutes).slice(-2); secondsSpan.innerHTML = ('0' + t.seconds).slice(-2); if (t.total <= 0) { clearInterval(timeinterval); } } updateClock(); var timeinterval = setInterval(updateClock, 1000); } // 处理LocalStorage存储逻辑 var savedTime = localStorage.getItem('saved_timer'); var deadline; if (savedTime === null) { // 首次访问,设置30天后的截止时间 deadline = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000); localStorage.setItem('saved_timer', deadline.getTime()); } else { // 读取时间戳并转为Date对象 deadline = new Date(parseInt(savedTime)); } initializeClock('clockdiv', deadline);
修复说明
- 优先存储和读取时间戳(数字类型),而非Date对象,确保跨环境解析一致,避免字符串格式差异导致的错误。
- 修正变量声明顺序,先判断LocalStorage值,再根据情况创建或读取截止时间,避免未定义变量问题。
- 优化
getTimeRemaining函数,直接使用Date对象的getTime()方法计算时间差,提升效率同时避免解析错误。
内容的提问来源于stack exchange,提问作者Kris Amipara
相关产品推荐
相关产品推荐

