通知 · API
通知的 actions 与 badge 选项
发布于 更新于
actions 给持久通知添加按钮,badge 提供完整通知放不下时操作系统显示的小型单色图片,例如 Android 状态栏。两者都是 ServiceWorkerRegistration.showNotification() 的 options 字典成员;在已发布的浏览器中,除了 Firefox 152 的 actions 之外都仅限 Chromium;两者都与 Badging API 设置的应用图标计数无关。
registration.showNotification(title, { badge: '/icons/badge-96.png', actions: [{ action: 'reply', title: '回复', icon: '/icons/reply.png' }],})Notification.maxActionsactions 只被 showNotification() 接受;向 new Notification() 传入非空数组会抛出 TypeError。Notification.maxActions 是静态 getter,返回引擎显示的按钮数量。支持情况:actions 在 Chrome 53、Edge 18、Firefox 152;badge 在 Chrome 53、Edge 18;Safari 两者都不支持(BCD api.Notification.actions、api.Notification.badge)。
| 成员 | 类型 | 含义 |
|---|---|---|
actions[].action |
string | 在 notificationclick 中以 event.action 返回的标识符。必填。 |
actions[].title |
string | 按钮文字。必填。 |
actions[].icon |
string(URL),可选 | 在绘制图标的平台(Android;Windows 不绘制)上显示在按钮上的图片。 |
actions[].navigate |
string(URL),可选 | Safari 18.4:打开该 URL 而不触发 notificationclick。Chromium 忽略它。 |
badge |
string(URL) | 紧凑形态使用的图片。Android 会把它遮罩成剪影并以最高 4 倍密度显示,因此带透明背景的 96 × 96 像素单色 PNG 是可用的尺寸。 |
Chromium 最多显示 kMaximumActions = 2 个按钮(notification.mojom,chromium.googlesource.com),多余的不报错直接丢弃;Firefox 152 通过 maxActions 报告自己的上限。读取这个 getter,不要把 2 写死。
| 异常 | 触发条件 |
|---|---|
TypeError |
new Notification() 上的 actions 非空。Chromium:Actions are only supported for persistent notifications shown using ServiceWorkerRegistration.showNotification(). |
TypeError |
某个 action 对象缺少 action 或 title,这两个是必填的字典成员。 |
不支持的选项不是异常:Firefox 152 之前的版本和 Safari 忽略 actions,Chromium 之外的所有引擎忽略 badge,通知只带正文显示。
actions 与 badge 在 Chrome 53(2016 年)一起发布,并随 Edge 转向 Chromium 到达 Edge;Firefox 在 152 加入了 actions 但仍忽略 badge;Safari 在 macOS 和 iOS 上两者都不支持,通知按钮不属于其 Web 通知界面(BCD api.Notification.actions、api.Notification.badge)。在 Android 上 badge 显示在状态栏和锁屏上;在 Windows 和 macOS 上 Chromium 忽略 badge,因为操作系统没有紧凑形态的位置。
示例把页面侧的 showNotification() 调用与读取 event.action 的 Service Worker 处理函数配对。
两个按钮,各自一个处理分支
Section titled “两个按钮,各自一个处理分支”Service Worker 读取 event.action。空字符串表示点的是通知主体,其他值是某个 action id。
// 页面await registration.showNotification('Ada 发来新消息', { body: '能把电话改到下午 3 点吗?', badge: '/icons/badge-96.png', tag: 'thread-42', data: { threadId: 42 }, actions: [ { action: 'reply', title: '回复' }, { action: 'mute', title: '静音此会话' }, ],});
// Service Workerself.addEventListener('notificationclick', (event) => { event.notification.close(); const { threadId } = event.notification.data; if (event.action === 'mute') { event.waitUntil(fetch(`/api/threads/${threadId}/mute`, { method: 'POST' })); } else { event.waitUntil(self.clients.openWindow(`/threads/${threadId}${event.action === 'reply' ? '#compose' : ''}`)); }});Chromium 的上限是两个,所以按「主要操作、破坏性操作」的顺序放;第三个按钮会被丢弃。
为 badge 图片定尺寸
Section titled “为 badge 图片定尺寸”badge 以剪影方式绘制:每个不透明像素都变成白色(或系统强调色),带内部细节的 logo 会变成一团。导出一个 96 × 96 像素、透明背景的单色图形。
await registration.showNotification('下载完成', { body: 'report-2026-q3.pdf', icon: '/icons/icon-192.png', // 全彩,显示在文字旁 badge: '/icons/badge-96.png', // 单色,显示在状态栏});icon 与 badge 服务于不同的位置,两者都值得设置;只有 icon 的通知在 Android 状态栏里显示的是浏览器自己的图标。
检测选项并在不支持处省略它们
Section titled “检测选项并在不支持处省略它们”支持这些选项的地方,它们是 Notification.prototype 的属性。按条件构建选项对象,同一个调用就能在 Safari 和 Firefox 里工作。
function notificationOptions(base, buttons) { if (!('Notification' in window)) return null; // 完全没有通知 const options = { ...base }; if ('badge' in Notification.prototype) options.badge = '/icons/badge-96.png'; if ('actions' in Notification.prototype && Notification.maxActions > 0) { options.actions = buttons.slice(0, Notification.maxActions); } return options;}按 maxActions 截取保留的是前几个按钮,而不是让引擎随意丢掉后面的;当数组顺序是「主要、次要、破坏性」时这一点很重要。
- Notifications API Standard: actions(whatwg.org)
- Notification: actions property(developer.mozilla.org)
- Notifications API
- Notification 接口
- Badging API
规范
| 规范 | 状态 |
|---|---|
| 无。 | |