You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);

问题原因与修复方案

核心问题分析

  1. 变量声明顺序错误:调用localStorage.setItem('saved_timer', saved_timer)时,saved_timer还未被声明,本地宽松模式可能未抛出错误,但服务器环境会导致该变量未定义,进而向LocalStorage存储了undefined值。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 10:57:31