网站娱乐时长追踪浏览器扩展开发技术咨询
核心问题解决方案
1. 强制用户输入时长限制
当用户访问娱乐网站时,通过content script在页面加载阶段触发检查:
- 先从
chrome.storage.local读取当前域名的时长配置(格式示例:{ site: "xxx.com", duration: 30, startTime: 123456789 }) - 如果没有配置,立即用你已实现的
generateHTML生成输入表单,通过document.body.innerHTML替换原页面内容,或添加全屏遮罩层覆盖原页面,阻止用户操作原网站内容 - 表单绑定提交事件,提交后将配置存入storage,再刷新页面让用户正常访问
示例代码片段(content.js):
(async function() { const currentSite = window.location.hostname; const config = await chrome.storage.local.get(currentSite); if (!config[currentSite]?.duration) { // 生成时长输入表单 const formHTML = ` <div style="position: fixed; top:0; left:0; width:100%; height:100%; background:white; display:flex; flex-direction:column; align-items:center; justify-content:center;"> <h2>请设置今日访问时长(分钟)</h2> <input type="number" id="durationInput" min="5" max="120" value="30"> <button id="submitBtn">确认</button> </div> `; document.body.innerHTML = formHTML; document.getElementById('submitBtn').addEventListener('click', async () => { const duration = parseInt(document.getElementById('durationInput').value); if (!duration || duration < 1) return; await chrome.storage.local.set({ [currentSite]: { duration, startTime: Date.now(), usedTime: 0, isBlocked: false, coolDownEnd: 0 } }); window.location.reload(); }); } else { checkTimeLimit(currentSite, config[currentSite]); } })();
2. 实现时段差异化冷却时间
先定义时段规则(可存入storage让用户自定义,或先硬编码),比如:
- 工作时段(9:00-18:00):冷却60分钟
- 休闲时段(18:00-次日9:00):冷却30分钟
在触发拦截逻辑时,获取当前时间的小时数,匹配时段计算冷却结束时间:
function getCoolDownDuration() { const hour = new Date().getHours(); return hour >=9 && hour <18 ? 60 * 60 * 1000 // 1小时毫秒数 : 30 * 60 * 1000; // 30分钟毫秒数 } // 超时后触发拦截 async function triggerBlock(site) { const coolDownEnd = Date.now() + getCoolDownDuration(); const currentConfig = (await chrome.storage.local.get(site))[site]; await chrome.storage.local.set({ [site]: { ...currentConfig, isBlocked: true, coolDownEnd } }); // 替换为拦截页面 document.head.innerHTML = generateSTYLES(); document.body.innerHTML = generateHTML(); }
3. 表单提交逻辑处理
结合第一个问题的表单,提交时需:
- 验证输入时长为有效正整数
- 将网站、时长、开始时间、已用时、拦截状态等信息存入
chrome.storage.local - 提交成功后刷新页面,同时在后台启动计时(推荐用
chrome.alarms,避免后台脚本休眠导致计时中断):
// 在background.js中设置闹钟 chrome.alarms.create(`timeLimit_${site}`, { delayInMinutes: duration }); // 监听闹钟触发事件 chrome.alarms.onAlarm.addListener((alarm) => { if (alarm.name.startsWith('timeLimit_')) { const site = alarm.name.replace('timeLimit_', ''); triggerBlock(site); } });
补充updateUI函数
这个函数负责根据当前状态更新页面或扩展UI,比如在拦截页面显示剩余冷却时间,或在浏览器工具栏图标上显示剩余时长:
async function updateUI(site) { const config = await chrome.storage.local.get(site); if (!config[site]) return; if (config[site].isBlocked) { const remaining = Math.ceil((config[site].coolDownEnd - Date.now()) / 60000); // 更新拦截页面的剩余时间显示 const timeEl = document.getElementById('remainingTime'); if (timeEl) timeEl.textContent = `剩余冷却时间:${remaining}分钟`; // 更新浏览器图标badge chrome.action.setBadgeText({ text: `${remaining}` }); chrome.action.setBadgeBackgroundColor({ color: '#FF0000' }); } else { const used = Math.ceil((Date.now() - config[site].startTime) / 60000); const remaining = config[site].duration - used; chrome.action.setBadgeText({ text: `${remaining > 0 ? remaining : 0}` }); chrome.action.setBadgeBackgroundColor({ color: '#00FF00' }); } }
弹窗HTML的选择建议
优先选择独立成文件,原因:
- 结构与逻辑分离,便于维护和修改HTML结构
- 支持独立的CSS样式文件,样式管理更清晰
- 符合Manifest V3规范,直接在manifest中配置即可:
// manifest.json { "action": { "default_popup": "popup.html", "default_icon": "icon.png" } }
如果是极简弹窗(仅几个按钮/文本),可以考虑嵌入JS,但不推荐,不利于后期扩展功能。
代码优化建议
- 模块化拆分:将功能拆分到不同文件:
content.js:处理页面注入、时长检查、拦截页面生成background.js:处理闹钟、storage监听、跨页面通信popup.js:处理弹窗交互、查看剩余时长、修改配置utils.js:封装通用函数(如时间计算、storage操作)
- 使用chrome.storage.session存储临时数据:比如当前页面的实时用时,避免频繁写入localStorage
- 添加错误处理:对storage操作、闹钟创建等添加try/catch,避免因权限或其他问题导致崩溃
- 支持用户自定义时段:在弹窗中添加时段配置功能,将规则存入storage,而非硬编码
内容的提问来源于stack exchange,提问作者Andreas Massey
相关产品推荐
相关产品推荐

