安装 · API
Badging API
发布于
Badging API(navigator.setAppBadge() 与 navigator.clearAppBadge(),service worker 内的 WorkerNavigator 上同样暴露)在已安装 web 应用位于任务栏、Dock 或主屏幕的图标上显示一个数字或一个圆点。Chrome 81 与 Edge 81 在 Windows、macOS、ChromeOS 上绘制它;Safari 16.4 为 iOS 主屏幕 web 应用绘制,Safari 17 为 macOS Dock web 应用绘制;Android 上的 Chrome 84 与 Samsung Internet 13 只对已安装应用、且启动器支持角标时生效;Firefox 没有实现(BCD api.Navigator.setAppBadge)。
await navigator.setAppBadge(); // 一个圆点("flag"),不带数字await navigator.setAppBadge(contents); // 一个数字;0 表示清除await navigator.clearAppBadge(); // 移除角标
// service worker 内,例如在 push 处理器中self.navigator.setAppBadge(count);两个方法都返回 Promise<void>,在请求交给操作系统后兑现,而不是在角标可见时。Chromium 上不涉及权限提示;iOS 上只有用户允许了已安装应用的通知之后才会绘制角标。
只有 setAppBadge() 接受参数。
| 名称 | 类型 | 说明 |
|---|---|---|
contents |
unsigned long long,可选 |
要显示的数字。0 清除角标,等同于 clearAppBadge()。省略时角标是一个不带数字的圆点。大数字如何显示由操作系统决定;规范把该值称为提示,允许平台缩写。 |
setAppBadge() 在两种情形下拒绝或抛出,在另外两种情形下静默无效。
TypeError:contents为负数、小数,或超出[EnforceRange] unsigned long long的范围。类型转换发生在创建 Promise 之前,因此 Chromium 中该错误是同步抛出的:Failed to execute 'setAppBadge' on 'Navigator': Value is outside the 'unsigned long long' value range.。InvalidStateError:调用方文档不处于 fully active 状态(例如已脱离文档的 iframe),这是规范中两个方法的第一步。- 无错误、无角标:应用未安装。Chromium 在普通标签页中兑现 Promise 但不绘制任何东西,所以角标只在安装后可见。
- 无错误、无角标:iOS 16.4 及以后,主屏幕 web 应用尚未获得通知权限(兼容性数据集备注)。调用兑现,图标保持原样。
Firefox 中 navigator.setAppBadge 为 undefined,未加保护的调用在触及 API 之前就会抛出 TypeError。
第一个示例运行在 service worker 中;第二个运行在页面中,并覆盖没有该 API 的浏览器。
把 push 事件里的未读数同步到图标
Section titled “把 push 事件里的未读数同步到图标”推送载荷若携带服务端的未读数,可以在用户打开应用之前就更新图标。event.waitUntil() 让 worker 存活到角标调用落定;在页面显示收件箱时调用 clearAppBadge(),可以保证图标与实际一致。
self.addEventListener('push', (event) => { const data = event.data?.json() ?? {}; const unread = Number.isInteger(data.unread) ? data.unread : 0; event.waitUntil(Promise.all([ self.registration.showNotification(data.title ?? 'New message'), self.navigator.setAppBadge(unread), ]));});
// page.js,在显示收件箱视图时navigator.clearAppBadge?.();在 Chromium 上只设角标而不显示通知是允许的,但在 iOS 上,不显示通知的 push 事件可能让应用失去推送订阅,所以上面的通知调用在 iOS 上不可省略。
检测支持并回退到文档标题
Section titled “检测支持并回退到文档标题”缺少 setAppBadge 时,唯一能跨浏览器承载计数的界面是标签页标题。下面的回退把计数作为前缀加到标题上,计数为零时去掉前缀。
function showUnread(count) { if ('setAppBadge' in navigator) { return count > 0 ? navigator.setAppBadge(count) : navigator.clearAppBadge(); } // 没有 Badging API(Firefox,或任何浏览器的普通标签页):改用标题。 const base = document.title.replace(/^\(\d+\) /, ''); document.title = count > 0 ? `(${count}) ${base}` : base; return Promise.resolve();}标题回退只在标签页打开期间可见,这正是 Badging API 消除的限制;对 Firefox 用户来说,这仍然比什么都不显示更合适。
- Badging API specification(w3c.github.io)
- Badging for app icons(developer.chrome.com)
- Badging API 浏览器支持
- 通知操作与角标
- Web Push
- iOS 添加到主屏幕
规范
| 规范 | 状态 |
|---|---|
| Badging API(角标) | W3C 草案 |
- 图例
- 支持
- 部分支持
- 需开启标志
- 不支持
- 未知
| 浏览器 / 平台 | 支持 | 版本 | 置信度 | 来源 | 备注 |
|---|---|---|---|---|---|
| Chrome (Android) | 部分支持 | 84 | 中 | 来源 | 1 |
| Chrome (Desktop) | 支持 | 81 | 中 | 来源 | — |
| Edge (Desktop) | 支持 | 81 | 中 | 来源 | — |
| Safari (iOS) | 支持 | 16.4 | 中 | 来源 | 2 |
| Safari (macOS) | 支持 | 17 | 中 | 来源 | — |
| Firefox (Desktop) | 不支持 | — | 中 | 来源 | 3 |
| Samsung Internet | 部分支持 | 13.0 | 中 | 来源 | 4 |
- 角标仅对已安装应用生效,且取决于启动器是否支持。
- 仅限主屏幕 Web 应用;与通知权限绑定。
- Firefox 没有实现 Badging API;`navigator.setAppBadge` 为 undefined(MDN 兼容性表,2026-10-03 核对)。
- 与 Chrome for Android 一致:角标仅对已安装 Web 应用显示,且取决于启动器是否支持。
在线试用
在 OpenPWA 演示应用中运行此能力: /demo/#badging