chrome.alarms API 实战指南:基于 chrome-extensions-samples 构建可交互的闹钟管理扩展
示例工程【免费下载链接】chrome-extensions-samplesChrome Extensions Samples项目地址https://gitcode.com/gh_mirrors/ch/chrome-extensions-samples点击查看免费下载导读本文基于 chrome-extensions-samples 仓库中的 api-samples/alarms 示例系统讲解 Manifest V3 下chrome.alarmsAPI 的完整用法。示例通过扩展页面让用户自由创建、查看、取消闹钟并实时记录触发日志覆盖了create、clear、clearAll、getAll与onAlarm监听器的全部核心场景。读完本文你将掌握定时任务扩展从「初始化默认闹钟」到「用户交互创建闹钟」的完整实现路径并能直接复用仓库中的代码搭建自己的闹钟应用。示例概览一个完整的闹钟管理 Demoapi-samples/alarms是一个轻量但功能完整的演示扩展安装扩展后后台 Service Worker 会自动创建一个初始闹钟同时打开 index.html 演示页面用户可以在页面上填写表单创建自定义闹钟实时查看当前闹钟列表与闹钟事件日志并逐个或全部取消闹钟。从仓库结构看该示例由以下文件组成文件职责manifest.jsonMV3 清单声明alarms权限与后台 Service Workerbg-wrapper.jsService Worker 入口通过importScripts加载业务逻辑background.js安装初始化、创建默认闹钟、打开演示页index.html演示页面结构创建表单、闹钟列表、日志区index.css页面样式index.js页面逻辑AlarmManager类封装全部闹钟操作README.md官方说明文档运行扩展的四个步骤按照 README.md 的指引运行该示例只需四步克隆仓库获取chrome-extensions-samples的完整代码。以加载已解压的扩展程序方式加载api-samples/alarms目录打开chrome://extensions开启开发者模式点击加载已解压的扩展程序选择该目录即可。将扩展固定到工具栏以便访问其操作按钮action button。点击操作按钮打开扩展弹窗/页面并与 UI 交互本示例中点击 action 会通过chrome.tabs.create打开index.html演示页而不是弹出一个 popup。注意本示例的manifest.json中action字段为空对象{}未声明默认弹窗default_popup因此点击按钮触发的是 background.js 中注册的chrome.action.onClicked监听器逻辑是打开演示标签页。清单配置声明 alarms 权限与后台脚本manifest.json 是 MV3 扩展的入口配置内容如下{ name: Alarms API Demo, version: 1.0, description: Uses the chrome.alarms API to allow the user to set alarms using an extension page., manifest_version: 3, background: { service_worker: bg-wrapper.js }, permissions: [alarms], action: {} }关键点有三permissions: [alarms]使用chrome.alarmsAPI 必须在清单中显式声明alarms权限否则 API 不可用。background: { service_worker: bg-wrapper.js }MV3 不再支持持久化的背景页取而代之的是事件驱动的 Service Worker。本示例采用wrapper 业务文件的双文件结构让业务逻辑可以像传统脚本一样被加载。action: {}声明操作按钮但未配置默认弹窗配合chrome.action.onClicked实现点击打开演示页的行为。bg-wrapper.js的全部内容只是一个容错加载器try { importScripts(background.js); } catch (error) { console.error(error); }将importScripts包裹在try/catch中即使业务脚本抛错Service Worker 也能继续存活便于在扩展调试页面排查问题。安装初始化自动创建默认闹钟background.js 承担了安装初始化职责。扩展首次安装时会打开演示页并创建一个占位闹钟保证用户进入演示页时有东西可看// Initialize the demo on install chrome.runtime.onInstalled.addListener(({ reason }) { if (reason ! chrome.runtime.OnInstalledReason.INSTALL) { return; } openDemoTab(); // Create an alarm so we have something to look at in the demo chrome.alarms.create(demo-default-alarm, { delayInMinutes: 1, periodInMinutes: 1 }); }); chrome.action.onClicked.addListener(openDemoTab); function openDemoTab() { chrome.tabs.create({ url: index.html }); }代码中有几个值得学习的工程细节区分安装原因onInstalled的reason只有等于INSTALL首次安装时才执行初始化逻辑更新UPDATE或浏览器更新BROWSER_UPDATE时不重复创建闹钟避免重复副作用。chrome.alarms.create(name, alarmInfo)的两种入参形式create的第一个参数是可选的闹钟名称省略时使用默认名。第二个参数alarmInfo必须提供when或delayInMinutes之一详见下文。周期闹钟同时指定delayInMinutes与periodInMinutes闹钟会在 1 分钟后首次触发之后每 1 分钟触发一次。打开页面复用同一函数openDemoTab同时被安装监听器和 action 点击监听器调用保证安装后与手动点击的体验一致。表单交互理解 when 与 delayInMinutes 两种计时方式演示页 index.html 中的创建表单包含三个输入闹钟名称alarm-name、初始延迟time-valuetime-format、重复周期period单位分钟。其中延迟时间支持两种单位——分钟minutes默认与毫秒milliseconds这正好对应chrome.alarms.create的两种计时参数。页面脚本 index.js 在表单提交时解析用户输入并组装alarmInfoform.addEventListener(submit, (event) { event.preventDefault(); const formData new FormData(form); const data Object.fromEntries(formData); const name data[alarm-name]; const delay Number.parseFloat(data[time-value]); const delayFormat data[time-format]; const period Number.parseFloat(data[period]); const alarmInfo {}; if (delayFormat ms) { // Specified in milliseconds, use when property alarmInfo.when Date.now() delay; } else if (delayFormat min) { // specified in minutes, use delayInMinutes property alarmInfo.delayInMinutes delay; } if (period) { alarmInfo.periodInMinutes period; } // Create the alarm – this uses the same signature as chrome.alarms.create manager.createAlarm(name, alarmInfo); });这段代码完整展示了alarmInfo的组装逻辑其背后对应chrome.alarms.create的参数约定alarmInfo 字段作用说明when绝对触发时间毫秒级时间戳例如Date.now() 5000表示 5 秒后触发when与delayInMinutes二者必须提供其一若同时提供when优先delayInMinutes相对延迟指定后闹钟在约delayInMinutes分钟后触发打包成 CRX 分发时最小值限制为 1 分钟详见下文periodInMinutes重复周期若提供闹钟会按此周期循环触发与when或delayInMinutes组合使用不提供则为一次性闹钟两个值得注意的点最小值限制表单下方特意标注了*提示——Can be set to 1 min in an unpacked extension, but not in a distributed CRX file.在未打包的扩展中可设置为小于 1 分钟但在分发的 CRX 文件中不可以。也就是说开发调试阶段unpacked 加载你可以用delayInMinutes: 0.1这类亚分钟值快速验证但如果要发布到 Chrome Web Store闹钟触发间隔至少首次触发必须不小于 1 分钟。这与when形式毫秒级绝对时间并不冲突后者在调试时同样能实现秒级触发。周期为 0 即一次性闹钟表单中period默认值为 0代码通过if (period)判断只有非零值才会写入periodInMinutes从而保证一次性闹钟与周期闹钟的行为正确切换。AlarmManager封装闹钟 CRUD 与日志记录页面逻辑的核心是AlarmManager类定义于 index.js它把chrome.alarms的所有操作封装为带日志输出的方法并将触发日志渲染到页面的Alarm log区。这类薄封装 日志的做法非常适合学习每一行 API 调用都有对应的可读日志闹钟生命周期一目了然。创建闹钟createAlarm// Thin wrapper around alarms.create to log creation event createAlarm(name, alarmInfo) { chrome.alarms.create(name, alarmInfo); const json JSON.stringify(alarmInfo, null, 2).replace(/\s/g, ); this.logMessage(Created ${name}\n${json}); this.refreshDisplay(); }create为异步操作同名的闹钟会被新闹钟覆盖重复创建同名闹钟时后创建的会替换先前的。创建后立即刷新显示区让新闹钟立刻出现在列表中。监听触发onAlarm构造函数中注册了chrome.alarms.onAlarm监听器constructor(display, log) { this.displayElement display; this.logElement log; this.logMessage(Manager: initializing demo); this.displayElement.addEventListener(click, this.handleCancelAlarm); chrome.alarms.onAlarm.addListener(this.handleAlarm); }handleAlarm是async箭头函数this绑定到实例收到alarm对象后把name与序列化后的完整 JSON 写入日志并刷新闹钟列表handleAlarm async (alarm) { const json JSON.stringify(alarm); this.logMessage(Alarm ${alarm.name} fired\n${json}}); await this.refreshDisplay(); };需要特别说明的是在 MV3 中chrome.alarms的主要使用场景正是 Service Worker 的定时唤醒——闹钟触发事件会唤醒休眠的 Service Worker让扩展能在不常驻后台的情况下周期性地执行任务例如清理缓存、轮询数据、发送通知。本示例把onAlarm放在扩展页面中监听是刻意为之的页面内演示方式方便初学者直接观察触发过程生产环境中的典型做法请参考下文仓库中的更多实践。取消与清空clear / clearAllcancelAlarm与cancelAllAlarms分别对应chrome.alarms.clear(name, callback)和chrome.alarms.clearAll(callback)。它们的回调参数wasCleared布尔值用于区分成功清除与闹钟不存在/已触发两种结果示例据此输出不同的日志async cancelAlarm(name) { return chrome.alarms.clear(name, (wasCleared) { if (wasCleared) { this.logMessage(Manager: canceled alarm ${name}); } else { this.logMessage(Manager: could not canceled alarm ${name}); } }); } async cancelAllAlarms() { return chrome.alarms.clearAll((wasCleared) { if (wasCleared) { this.logMessage(Manager: canceled all alarms); } else { this.logMessage(Manager: could not canceled all alarms); } }); }列表渲染与防抖刷新getAllpopulateDisplay调用chrome.alarms.getAll(callback)获取全部闹钟并逐个渲染成带cancel按钮的行async populateDisplay() { return chrome.alarms.getAll((alarms) { for (const [index, alarm] of alarms.entries()) { const isLast index alarms.length - 1; this.renderAlarm(alarm, isLast); } }); }refreshDisplay则用一个私有字段#refreshing实现简单的锁机制防止并发刷新导致列表重复渲染#refreshing false; async refreshDisplay() { if (this.#refreshing) { return; } // refresh in progress, bail this.#refreshing true; // acquire lock try { await this.clearDisplay(); await this.populateDisplay(); } finally { this.#refreshing false; // release lock } }这里的#前缀是 ES2022 的私有类字段语法finally确保锁在任何情况下都会释放。闹钟触发、创建、取消三个异步入口都可能触发refreshDisplay这个锁有效避免了竞态条件下列表出现重复条目。仓库中的更多实践闹钟与通知、徽章联动除了api-samples/alarms这个教学示例仓库里还有多个以chrome.alarms为核心的实战样例可作为扩展学习的第二站sample.water_alarm_notification一个喝水提醒扩展。其 background.js 展示了纯 Service Worker 场景下的完整闭环——用户点击通知按钮后从chrome.storage.sync读取提醒间隔并创建周期闹钟闹钟触发时onAlarm清除 action 徽章并创建系统通知chrome.alarms.onAlarm.addListener(() { chrome.action.setBadgeText({ text: }); chrome.notifications.create({ type: basic, iconUrl: stay_hydrated.png, title: Time to Hydrate, message: Everyday Im Guzzlin!, buttons: [{ title: Keep it Flowing. }], priority: 0 }); }); chrome.notifications.onButtonClicked.addListener(async () { const item await chrome.storage.sync.get([minutes]); chrome.action.setBadgeText({ text: ON }); chrome.alarms.create({ delayInMinutes: item.minutes }); });注意这里的chrome.alarms.create({ delayInMinutes: item.minutes })省略了闹钟名称参数——此时闹钟使用默认名属于 API 的合法用法。tutorial.mole-game 与 tutorial.open-api-reference、tutorial.quick-api-reference分别在游戏控制器与 API 参考工具中通过onAlarm驱动 Service Worker 的周期性行为如生成提示、刷新内容印证了alarms Service Worker是 MV3 定时任务的标准组合。对比可见api-samples/alarms的页面化展示更利于理解 API 每次调用的即时效果而 water_alarm_notification 等样例更贴近真实产品形态两者结合能帮你从会用 API进阶到会设计定时任务架构。常见问题与注意事项结合本示例的代码与 Chrome 的 API 约束总结如下实践要点权限必须声明忘记在 manifest.json 中添加permissions: [alarms]是新手最常见的报错来源。when与delayInMinutes必须提供其一否则chrome.alarms.create会报错两者同时提供时以when为准。分发的扩展闹钟间隔不能小于 1 分钟CRX / Web Store 场景unpacked 调试不受限用when: Date.now() delay可在调试时实现毫秒级触发。同名闹钟会被覆盖再次调用create时若名称相同新配置会替换旧配置。清除回调的wasCleared值得检查它帮助区分清除成功与该闹钟早已触发完一次性闹钟触发后自动消失。MV3 中闹钟是 Service Worker 的唤醒机制不要依赖页面存活来维持定时任务onAlarm应注册在后台脚本中本示例的页面内监听是教学演示真实产品请参照 water_alarm_notification 的写法。总结api-samples/alarms用不到百行页面脚本完整呈现了chrome.alarms的五个核心 APIcreate、clear、clearAll、getAll、onAlarm与两种计时模型when绝对时间 /delayInMinutes相对延迟并通过AlarmManager类示范了如何将异步回调 API 封装为带日志、带防抖刷新、可测试的界面逻辑。结合仓库中 water_alarm_notification 等实战样例你可以快速掌握闹钟 Service Worker 通知这一 MV3 定时任务最佳实践并将其迁移到自己的扩展中。赞分享示例工程【免费下载链接】chrome-extensions-samplesChrome Extensions Samples项目地址https://gitcode.com/gh_mirrors/ch/chrome-extensions-samples点击查看免费下载相关推荐JavaScript变量提升和作用域通过JavaScript Challenges Book掌握闭包和条件语句JavaScript变量提升和作用域通过JavaScript Challenges Book掌握闭包和条件语句 JavaScript Challenges B示例工程如何快速上手 WrenAI从安装到第一次跑通自然语言查询如何快速上手 WrenAI从安装到第一次跑通自然语言查询 WrenAI 是一个开源的生成式 BIGenBI引擎它让 AI 智能体通过受治理的 text示例工程chrome-extensions-samples 实战基于 chrome.tabs.captureVisibleTab() 实现标签页截图扩展chrome extensions samples 实战基于 chrome.tabs.captureVisibleTab 实现标签页截图扩展 导读 本文以 c示例工程上一篇终极MonkeyDev教程零基础实现非越狱iOS设备的微信自定义功能下一篇突破直播瓶颈Owncast启用Intel Quick Sync加速编码的完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

gbrain v0.18.0 多源大脑(Multi-source Brains)迁移与配置实战:一个数据库承载多个知识仓库

gbrain v0.18.0 多源大脑(Multi-source Brains)迁移与配置实战:一个数据库承载多个知识仓库

人工智能RAGAgent 记忆MCP 服务知识管理 【免费下载链接】gbrain Garrys Opinionated OpenClaw/Hermes Agent Brain 项目地址: https://gitcode.com/gh_mirrors/gb/gbrain 点击查看 免费下载 本指南以 skills/migrations/v0.18.0.md 迁移文档为核心骨架&#xff0c…

2026/9/21 7:38:43 阅读更多 →
Flink Table SQL DELETE 语句完全指南:行级删除、语法与连接器实现机制

Flink Table SQL DELETE 语句完全指南:行级删除、语法与连接器实现机制

大数据流处理批处理数据工程 【免费下载链接】flink 项目地址: https://gitcode.com/gh_mirrors/fli/flink 点击查看 免费下载 DELETE 是 Flink Table API & SQL 提供的行级删除语句,用于按照 WHERE 条件批量删除目标表中的数据。本指南以 Flink 官…

2026/9/21 7:38:43 阅读更多 →
Paseo 插件实战:用 Timeline Transformer 把 Agent 推理过程改造成内联思维链渲染

Paseo 插件实战:用 Timeline Transformer 把 Agent 推理过程改造成内联思维链渲染

【免费下载链接】paseo Orchestrate multiple coding agents from desktop and mobile 项目地址: https://gitcode.com/gh_mirrors/pa/paseo 点击查看 免费下载 Paseo 的插件系统允许客户端通过 Timeline Transformer 与 Timeline Renderer 接管 Agent 时间线上任意…

2026/9/21 7:38:43 阅读更多 →

最新新闻

3类高危漏洞:网页制作模板中文源码下载安全自查

3类高危漏洞:网页制作模板中文源码下载安全自查

3类高危漏洞:网页制作模板中文源码下载安全自查 域名服务器搞不懂,是无数运营推广人员接手“网页制作模板中文”项目时的噩梦。你手里拿着一个看起来很漂亮的模板,后台却像个黑盒,更别提那些藏在代码深处的安全隐患。…

2026/9/21 8:30:15 阅读更多 →
汽车之家网页版地址排查指南:3步定位挂马源,附前端布局对比评测

汽车之家网页版地址排查指南:3步定位挂马源,附前端布局对比评测

汽车之家网页版地址排查指南:3步定位挂马源,附前端布局对比评测 网站被黑挂马,后台却一片空白,这种绝望感每个运维和前端都懂。别慌,这通常不是代码逻辑错误,而是服务器环境或静态资源被篡改。今天不聊虚的,直接上干货,用 对比评测 的思路,带你从 汽车之家网页版地址…

2026/9/21 8:14:36 阅读更多 →
企业网站做电脑营销避坑指南:选哪家好别只看价格,看这套设计规范

企业网站做电脑营销避坑指南:选哪家好别只看价格,看这套设计规范

企业网站做电脑营销避坑指南:选哪家好别只看价格,看这套设计规范 改个需求建站公司拖一周,这种憋屈事谁没经历过?很多老板找企业网站做电脑营销,问得最多的一句话就是“哪家好”。其实,网站好不好用,营销转不转化,核心不在你付了多少钱,而在前端代码写得够不够规范,设计逻辑是否支撑你的业务目标。…

2026/9/21 8:00:00 阅读更多 →
做品管圈网站哪家好?3步避开被黑挂马陷阱

做品管圈网站哪家好?3步避开被黑挂马陷阱

做品管圈网站哪家好?3步避开被黑挂马陷阱 网站上线三天,后台突然多了个奇怪的脚本,页面弹出一堆博彩广告,SEO排名一夜清零。如果你正面临这种“网站被黑挂马不知道怎么办”的噩梦,先别慌着删库重装。很多站长在找做品管圈网站哪家好时,只盯着价格和功能,却忽略了最底层的代码安全与架构选型。今天咱们不聊虚的,…

2026/9/21 7:44:43 阅读更多 →
Voyager 資料夾管理指南:為 Gemini 與 AI Studio 的 AI 對話打造真正的「檔案系統」

Voyager 資料夾管理指南:為 Gemini 與 AI Studio 的 AI 對話打造真正的「檔案系統」

AI 应用前端 【免费下载链接】voyager Enhancement suite for Gemini, AI Studio, Claude & ChatGPT — plus a prompt manager for any websites, DeepSeek Harness included. / 面向 Gemini、AI Studio、Claude 与 ChatGPT 的增强套件;其中的提示词管理器可用…

2026/9/21 7:41:44 阅读更多 →
gatsby-source-graphql 插件全解析:将任意第三方 GraphQL API 缝合进 Gatsby 数据层

gatsby-source-graphql 插件全解析:将任意第三方 GraphQL API 缝合进 Gatsby 数据层

前端静态站点Web框架 【免费下载链接】gatsby React-based framework with performance, scalability, and security built in. 项目地址: https://gitcode.com/gh_mirrors/ga/gatsby 点击查看 免费下载 本篇技术指南以 gatsby-source-graphql 插件的 CHANGELOG 版…

2026/9/21 7:41:44 阅读更多 →

日新闻

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程

agents-generator 决策矩阵全解析:从项目检测到 AGENTS.md 规则生成的 16 步判定流程 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and …

2026/9/21 0:00:01 阅读更多 →
gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析

gin-vue-admin 前端工具函数全景指南:src/utils 复用规范与源码级解析 【免费下载链接】gin-vue-admin 🚀ViteVue3Gin拥有AI辅助的基础开发平台,企业级业务AI开发解决方案,内置mcp辅助服务,内置skills管理,…

2026/9/21 0:00:01 阅读更多 →
Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

Wox 全功能插件开发实战指南:基于 Python / Node.js 宿主与 WebSocket 的持久化插件体系

桌面应用AI 应用插件系统 【免费下载链接】Wox A cross-platform launcher that simply works 项目地址: https://gitcode.com/gh_mirrors/wo/Wox 点击查看 免费下载 全功能插件(Full-featured Plugin)是 Wox 三类插件实现方式中能力最完整的…

2026/9/21 0:00:01 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/21 3:13:20 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/21 2:19:36 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/21 4:51:05 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →