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

如何实现考试计时器页面刷新后从剩余时间继续计时?

实现考试计时器页面刷新后继续计时的解决方案

要解决页面刷新后计时器重置的问题,核心是在页面关闭/刷新前把剩余时间存起来,页面加载时读取这个时间再启动计时器。你的代码思路是对的,但存在几个细节问题,下面是修正方案:

主要问题及修正点

  • 变量作用域问题:原代码里的time是startTimer函数的局部变量,beforeunload事件无法访问,导致无法正确保存剩余时间。需要把时间和计时器实例设为全局变量。
  • 事件绑定错误:window没有onload这个事件名,正确的事件是load,或者用DOMContentLoaded(更推荐,DOM加载完成就触发)。
  • Cookie读取逻辑缺陷:直接用cookie.split("=")[1]会在多个Cookie时出错,需要专门提取目标Cookie值。
  • 计时器初始化逻辑缺失:页面加载后如果有保存的剩余时间,应该用这个时间启动计时器,而不是默认值。

修正后的完整代码

// 全局变量,保存剩余时间和计时器实例
let remainingTime = 305; // 默认考试时长(秒)
let counterTime = null;

// 格式化时间为HH:MM:SS的工具函数,提取出来避免重复定义
String.prototype.toHHMMSS = function () {
    const sec_num = parseInt(this, 10);
    const hours = Math.floor(sec_num / 3600);
    const minutes = Math.floor((sec_num - hours * 3600) / 60);
    const seconds = sec_num - hours * 3600 - minutes * 60;

    return [
        hours.toString().padStart(2, '0'),
        minutes.toString().padStart(2, '0'),
        seconds.toString().padStart(2, '0')
    ].join(':');
};

function startTimer(time) {
    // 先清除之前的计时器,避免重复启动
    if (counterTime) clearInterval(counterTime);
    
    remainingTime = time;
    counterTime = setInterval(timerCount, 1000);

    function timerCount() {
        // 剩余时间提醒逻辑
        if (remainingTime <= 600) {
            const iconItem = document.querySelector(".btn-shop + p");
            iconItem.style.color = "#F7931E";
            iconItem.style.fontSize = "2.4rem";

            const icon = document.querySelector(".fa-clock");
            icon.classList.add("shake-bottom");
            icon.style.animationIterationCount = "infinite";
        }

        if (remainingTime <= 300) {
            const iconItem = document.querySelector(".btn-shop + p");
            iconItem.style.color = "#d52039";
            iconItem.style.fontSize = "2.4rem";

            const icon = document.querySelector(".fa-clock");
            icon.classList.add("shake-bottom");
            icon.style.animationIterationCount = "infinite";
        }

        // 时间到跳转页面
        if (remainingTime === 0) {
            window.location.replace("./dashb-final-examen.html");
            clearInterval(counterTime);
            // 时间到后清除Cookie
            document.cookie = "examTime=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
            return;
        }

        // 更新页面显示的时间
        document.getElementById("timer").textContent = remainingTime.toString().toHHMMSS();
        remainingTime--;
    }
}

// 页面加载时读取Cookie中的剩余时间
document.addEventListener("DOMContentLoaded", function() {
    // 提取time对应的Cookie值
    const cookies = document.cookie.split('; ');
    const timeCookie = cookies.find(cookie => cookie.startsWith('examTime='));
    
    if (timeCookie) {
        const savedTime = parseInt(timeCookie.split('=')[1], 10);
        // 只有保存的时间大于0才用这个值启动计时器
        if (!isNaN(savedTime) && savedTime > 0) {
            remainingTime = savedTime;
        }
    }
    // 启动计时器
    startTimer(remainingTime);
});

// 页面卸载前保存剩余时间到Cookie
window.addEventListener("beforeunload", function(e) {
    if (remainingTime > 0) {
        // 设置Cookie有效期,确保在整个网站范围内可访问
        document.cookie = `examTime=${remainingTime}; path=/; SameSite=Lax`;
    } else {
        // 时间到清除Cookie
        document.cookie = "examTime=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
    }
});

额外说明

  • 把时间格式化函数提取到全局,避免每次计时器回调都重新定义,提升性能。
  • 启动计时器前先清除旧的计时器,防止重复触发计时。
  • Cookie加上path=/确保在整个网站范围内可访问,SameSite=Lax提升安全性。
  • 时间到后主动清除Cookie,避免下次加载时读取到过期时间。

内容的提问来源于stack exchange,提问作者Edinson Morales

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:40:31