Chrome扩展弹窗倒计时关闭/刷新后停止,如何实现后台持续计时?
实现方案
问题根因:Chrome扩展的弹窗是临时页面上下文,关闭后页面内所有运行逻辑(包括你写的setInterval定时器)会直接销毁,你当前只存储了上次退出时的剩余秒数,没有记录倒计时的绝对结束时间,因此重新打开弹窗时无法计算中间流失的时长,只能从上次存储的暂停数值继续走。
核心实现思路:放弃存储剩余倒计时秒数,改为存储倒计时的结束时间戳,每次打开弹窗时通过当前时间戳和结束时间戳的差值计算真实剩余时长。如果需要倒计时结束后即使没打开弹窗也能执行逻辑(比如弹出通知),可以配合扩展的Service Worker后台线程实现。
具体代码修改
const lifetime = document.getElementById('premium-btn'); const countdown = document.getElementById('countdown'); // 倒计时总时长 单位:秒 const TOTAL_SECONDS = 345600; let timer = null; // 跳转按钮逻辑 lifetime.addEventListener('click', function() { window.open("https://flutterwave.com/pay/fonsnatcher-lifetime", "_blank"); }); // 初始化倒计时 initCountdown(); function initCountdown() { chrome.storage.sync.get(['endTimestamp'], function(result) { let endTimestamp = result.endTimestamp; // 没有存储的结束时间,说明是第一次启动倒计时 if (!endTimestamp) { endTimestamp = Date.now() + TOTAL_SECONDS * 1000; chrome.storage.sync.set({endTimestamp: endTimestamp}); } // 启动倒计时渲染 startRender(endTimestamp); }); } function startRender(endTimestamp) { // 先渲染一次避免1秒空白 renderRemainTime(endTimestamp); timer = setInterval(() => { const isEnd = renderRemainTime(endTimestamp); if (isEnd) { clearInterval(timer); countdown.innerHTML = "Completed"; // 可以在这里加结束后的前端逻辑 } }, 1000) } // 渲染剩余时间,返回是否已经结束 function renderRemainTime(endTimestamp) { const now = Date.now(); const remainSeconds = Math.floor((endTimestamp - now) / 1000); // 倒计时已结束 if (remainSeconds <= 0) { return true; } displayTime(remainSeconds); return false; } function displayTime(second) { const days = Math.floor(second / 24 / 60 / 60); const hoursLeft = second - days * 86400; const hours = Math.floor(hoursLeft / 3600); const minsLeft = hoursLeft - hours * 3600; const min = Math.floor(minsLeft / 60); const sec = Math.floor(second % 60); countdown.innerHTML = `${ days < 10 ? '0' : '' }${ days }:${ hours < 10 ? '0' : '' }${ hours }:${ min < 10 ? '0' : '' }${ min }:${ sec < 10 ? '0' : '' }${ sec }`; } function onTimeEnd() { // 结束逻辑可以写在这里 }
可选:后台触发结束逻辑
如果需要倒计时结束后即使未打开弹窗也能执行操作(比如弹出浏览器通知),需要配合扩展的Service Worker实现:
- 在
manifest.json中注册Service Worker,同时开启storage、notifications权限 - 在Service Worker中监听存储的
endTimestamp,到达结束时间时触发对应操作即可
内容的提问来源于stack exchange,提问作者Hitman DD
相关产品推荐
相关产品推荐

