1. 术语
本规范依赖于 Infra 标准。[INFRA]
本规范中使用的一些术语在 DOM、Fetch、高精度时间、HTML、IDL、Service Workers、URL 和振动 API 标准中定义。 [DOM] [FETCH] [HR-TIME] [HTML] [WEBIDL] [SERVICE-WORKERS] [URL] [VIBRATION]
2. 通知
通知是已发生事件的抽象表示,例如消息的传递。
通知有一个关联的 service worker 注册(null 或一个 service worker 注册)。初始值为 null。
通知 有一个关联的 标题(一个字符串)。
通知
有一个关联的
方向("auto
"、"ltr
"
或 "rtl
")。
通知 有一个关联的 语言(一个字符串)。
通知 有一个关联的 正文(一个字符串)。
通知 有一个关联的 导航 URL (null 或一个 URL)。初始值为 null。
通知 有一个关联的 标签(一个字符串)。
通知
有一个关联的 时间戳
(一个 EpochTimeStamp
)。
时间戳可用于指示通知的实际时间。例如,当设备离线而无法立即传递消息时,这可能是过去的时间,或者对于即将开始的会议,这可能是未来的时间。
通知 有一个关联的 重新通知偏好(一个布尔值)。初始值为 false。当为 true 时,表示在运行了通知显示步骤后,如果新通知与现有通知具有相同的标签,应该提醒终端用户。
通知 有一个关联的 静音偏好(null 或一个布尔值)。初始值为 null。当为 true 时,表示不应产生声音或振动。当为 null 时,表示产生声音或振动应遵循平台约定。
通知 有一个关联的 需要交互偏好 (一个布尔值)。初始值为 false。当为 true 时,表示在具有足够大屏幕的设备上,通知应保持可用状态,直到终端用户激活或关闭通知。
通知 可以具有这些关联的图形:一个 图像 URL、 图标 URL 和 徽章 URL;以及它们对应的 图像资源、图标资源 和 徽章资源。
图像资源是作为通知内容一部分显示的图片,应该比图标资源和徽章资源具有更高的视觉优先级,尽管它可能在较少的情况下显示。
图标资源是增强通知的图像(例如图标或发送者的照片)。
徽章资源是代表 Web 应用程序的图标,或者如果 Web 应用程序发送各种各样的通知,则代表通知的类别。当没有足够空间显示通知本身时,可以用它来表示通知。它也可以在通知内部显示,但那时它应该比图像资源和图标资源具有较低的视觉优先级。
通知 有一个关联的 振动模式(一个 列表)。初始值为 « »。
鼓励开发者不要通过图像、图标、徽章或振动模式传达终端用户无法以其他方式访问的信息,特别是因为不支持这些功能的通知平台可能会忽略它们。
通知 有关联的 操作 (零个或多个通知操作的列表)。通知操作代表终端用户的选择。每个通知操作都有一个关联的:
- 名称
- 一个字符串。
- 标题
- 一个字符串。
- 导航 URL
- Null 或一个 URL。初始值为 null。
- 图标 URL
- Null 或一个 URL。初始值为 null。
- 图标资源
- Null 或一个资源。初始值为 null。
用户可以激活操作,作为激活通知本身的替代方案。支持的最大操作数量是一个实现定义的零或更多的整数,在通知平台的约束范围内。
由于操作的显示取决于平台,鼓励开发者确保终端用户可以从通知中调用的任何操作在 Web 应用程序中也可用。
某些平台可能会在向终端用户显示之前修改图标资源以更好地匹配平台的视觉风格,例如通过圆化边角或用特定颜色绘制。鼓励开发者使用能够优雅处理此类情况并且不会因为例如颜色丢失或边角被裁剪而丢失重要信息的图标。
非持久通知是其通知的service worker 注册为 null 的通知。
持久通知是其通知的service worker 注册非 null 的通知。
要使用设置对象创建通知,给定字符串 title、
NotificationOptions
字典 options 和
环境设置对象 settings:
-
令 origin 为 settings 的 源。
-
令 baseURL 为 settings 的 API 基础 URL。
-
令 fallbackTimestamp 为从 Unix 纪元到 settings 的 当前挂钟时间的毫秒数,舍入到最接近的整数。
-
返回创建通知给定 title、 options、origin、baseURL 和 fallbackTimestamp 的结果。
要创建通知,给定字符串
title、
NotificationOptions
字典 options、源
origin、URL baseURL 和 EpochTimeStamp
fallbackTimestamp:
-
令 notification 为新的通知。
-
如果 options["
silent
"] 为 true 并且 options["vibrate
"] 存在,则抛出TypeError
。 -
如果 options["
renotify
"] 为 true 并且 options["tag
"] 为空字符串,则抛出TypeError
。 -
将 notification 的数据设置为 StructuredSerializeForStorage(options["
data
"])。 -
将 notification 的标题设置为 title。
-
将 notification 的源设置为 origin。
-
如果 options["
navigate
"] 存在,则使用 baseURL 解析它,如果解析不返回失败,则将 notification 的导航 URL 设置为返回值。(否则 notification 的导航 URL 保持为 null。) -
如果 options["
image
"] 存在,则使用 baseURL 解析它,如果解析不返回失败,则将 notification 的图像 URL 设置为返回值。(否则 notification 的图像 URL 不设置。) -
如果 options["
icon
"] 存在,则使用 baseURL 解析它,如果解析不返回失败,则将 notification 的图标 URL 设置为返回值。(否则 notification 的图标 URL 不设置。) -
如果 options["
badge
"] 存在,则使用 baseURL 解析它,如果解析不返回失败,则将 notification 的徽章 URL 设置为返回值。(否则 notification 的徽章 URL 不设置。) -
如果 options["
vibrate
"] 存在,则 验证和规范化它,并将 notification 的 振动模式设置为返回值。 -
如果 options["
timestamp
"] 存在,则将 notification 的时间戳设置为该值. 否则,将 notification 的时间戳设置为 fallbackTimestamp。 -
将 notification 的需要交互偏好设置为 options["
requireInteraction
"]。 -
将 notification 的操作设置为 « »。
-
返回 notification。
2.1. 生命周期和用户界面集成
用户代理必须维护一个 通知列表,它是一个 列表,包含零个或多个 通知。
用户代理不应在平台的“通知中心”(如有)显示 非持久通知。
可以通过调用其 close()
方法关闭某个 持久通知 的 Notification
对象。
用户代理应在平台的“通知中心”(如有)显示 持久通知。
2.2. 权限集成
通知 API 是一个 强大功能,通过 名称 "notifications
" 进行标识。
[Permissions]
要获取通知权限状态,请运行以下步骤:
-
令 permissionState 为使用 "
notifications
" 获取当前权限状态 的结果。 -
如果 permissionState 为 "
prompt
",则返回 "default
"。 -
返回 permissionState。
2.3. 方向
本节采用与 HTML 渲染部分等效的术语编写。[HTML]
用户代理应遵循通知 通知 的
标题、正文以及每个 操作 的 标题的 Unicode 语义。每个都应在显示时作为双向算法规则 P1、P2、P3 定义的一个或多个独立段落处理,包括例如支持 U+000A
换行符的段落分割行为。对于 标题、正文和每个 操作 的 标题的每个段落,如果 通知 的 方向 不为 "auto
",则它提供了对规则 P2 和 P3 的高层覆盖。[BIDI]
通知的 方向还决定了 通知的 操作在通知平台并排显示时向终端用户展示的相对顺序。
2.4. 语言
通知的 语言指定了 通知的 标题、正文以及每个 操作 的 标题的主要语言。其值为字符串。空字符串表示主要语言未知。其他字符串必须被解释为语言标签。不会强制有效性或格式正确。[BCP47]
鼓励开发者仅使用有效的语言标签。
2.5. 资源
获取步骤,用于给定 通知 notification:
-
如果通知平台支持图片,则 获取 notification 的 图片 URL(如果已设置)。
意图是类似于
<img>
的方式获取该资源,但这 需要抽象。然后,并行:
-
如果通知平台支持图标,则 获取 notification 的 图标 URL(如果已设置)。
意图是类似于
<img>
的方式获取该资源,但这 需要抽象。然后,并行:
-
如果通知平台支持徽章,则 获取 notification 的 徽章 URL(如果已设置)。
意图是类似于
<img>
的方式获取该资源,但这 需要抽象。然后,并行:
-
如果通知平台支持操作和操作图标,则对于 notification 的每个 action:如果 图标 URL 非空,则 获取 action 的 图标 URL。
意图是类似于
<img>
的方式获取该资源,但这 需要抽象。然后,并行:
2.6. 显示通知
通知显示步骤,用于给定的通知 notification:
-
为 notification 运行获取步骤。
-
等待任何获取完成,以及 notification 的 图像资源、 图标资源和 徽章资源 被设置(如果有),以及 notification 的 操作的 图标 资源(如果有)。
-
令 shown 为 false。
-
令 oldNotification 为通知列表中的通知,其标签不是空字符串且与 notification 的标签相同, 并且其源与 notification 的源同源(如果有),否则为 null。
-
如果 oldNotification 非 null,则:
-
如果 shown 为 false,则:
-
如果 shown 为 false 或 oldNotification 非 null,并且 notification 的重新通知偏好为 true,则为 notification 运行提醒步骤。
-
如果 notification 是非持久通知,则队列任务以在代表 notification 的
Notification
对象上触发事件,事件名为show
。
2.7. 激活通知
当通知 notification 或其 操作之一被终端用户激活时, 假设底层通知平台支持激活,用户代理必须(除非另有规定)运行以下步骤:
-
令 action 为 null。
-
令 navigationURL 为 notification 的 导航 URL。
-
如果 action 非 null,则将 navigationURL 设置为 action 的 导航 URL。
-
如果 navigationURL 非 null:
-
以实现定义的方式从以下两个选项中选择一个:
-
给定 navigationURL,创建一个新的顶级 可遍历。
强烈鼓励用户代理匹配平台约定。
-
返回。
-
-
如果 notification 是持久通知,则:
-
令 actionName 为空字符串。
-
如果 action 非 null,则将 actionName 设置为 action 的 名称。
- 给定 notification 和 actionName,触发 Service Worker 通知
事件,事件名为 "
notificationclick
"。
-
-
否则,队列任务以运行以下步骤:
-
令 intoFocus 为在代表 notification 的
Notification
对象上触发事件的结果,事件名为click
,其cancelable
属性初始化为 true。鼓励用户代理使
focus()
在名为click
的事件的事件监听器中工作。 -
如果 intoFocus 为 true,则用户代理应该将 notification 相关的浏览上下文的视口带入焦点。
-
在整个 Web 平台中,"activate" 故意被错误命名为 "click"。
2.8. 关闭通知
当通知被关闭时,无论是由底层通知平台还是由 终端用户关闭,都必须运行其关闭步骤。
关闭步骤,用于给定的 通知 notification:
给定通知 notification,处理关闭 事件:
-
如果 notification 是持久通知且 notification 被终端用户关闭,则给定 notification,触发 Service Worker 通知 事件,事件名为 "
notificationclose
"。 -
如果 notification 是非持久通知,则队列任务以在代表 notification 的
Notification
对象上触发事件,事件名为close
。
2.9. 提醒终端用户
3. API
[Exposed =(Window ,Worker )]interface :
Notification EventTarget {constructor (DOMString ,
title optional NotificationOptions = {});
options static readonly attribute NotificationPermission permission ; [Exposed =Window ]static Promise <NotificationPermission >requestPermission (optional NotificationPermissionCallback );
deprecatedCallback static readonly attribute unsigned long maxActions ;attribute EventHandler onclick ;attribute EventHandler onshow ;attribute EventHandler onerror ;attribute EventHandler onclose ;readonly attribute DOMString title ;readonly attribute NotificationDirection dir ;readonly attribute DOMString lang ;readonly attribute DOMString body ;readonly attribute USVString navigate ;readonly attribute DOMString tag ;readonly attribute USVString image ;readonly attribute USVString icon ;readonly attribute USVString badge ; [SameObject ]readonly attribute FrozenArray <unsigned long >vibrate ;readonly attribute EpochTimeStamp timestamp ;readonly attribute boolean renotify ;readonly attribute boolean ?silent ;readonly attribute boolean requireInteraction ; [SameObject ]readonly attribute any data ; [SameObject ]readonly attribute FrozenArray <NotificationAction >actions ;undefined close (); };dictionary {
NotificationOptions NotificationDirection = "auto";
dir DOMString = "";
lang DOMString = "";
body USVString ;
navigate DOMString = "";
tag USVString ;
image USVString ;
icon USVString ;
badge VibratePattern ;
vibrate EpochTimeStamp ;
timestamp boolean =
renotify false ;boolean ?=
silent null ;boolean =
requireInteraction false ;any =
data null ;sequence <NotificationAction >= []; };
actions enum {
NotificationPermission ,
"default" ,
"denied" };
"granted" enum {
NotificationDirection ,
"auto" ,
"ltr" };
"rtl" dictionary {
NotificationAction required DOMString ;
action required DOMString ;
title USVString ;
navigate USVString ; };
icon callback =
NotificationPermissionCallback undefined (NotificationPermission );
permission
一个非持久通知由一个Notification
对象表示,可以通过Notification
的
构造函数创建。
一个持久通知
由零个或多个Notification
对象表示,可以通过
showNotification()
方法创建。
3.1. 垃圾回收
当通知列表
包含其对应的通知且其具有
事件监听器时,Notification
对象不得被垃圾回收。事件监听器的类型为click
、show
、
close
或error
。
3.2. 构造函数
new Notification(title, options)
构造函数的步骤如下:
3.3. 静态成员
静态permission
获取器的步骤是返回
获取通知权限状态的结果。
如果您编辑标准,请避免复制上述内容。同步权限就像同步 IO,是一个糟糕的主意。
鼓励开发者使用权限query()
方法。[Permissions]
const permission = await navigator.permissions.query({name: "notifications"}); if (permission.state === "granted") { // 我们有权限使用该 API… }
静态
requestPermission(deprecatedCallback)
方法的步骤如下:
-
让global为当前全局对象。
-
让promise为一个新 promise,位于this的相关 Realm中。
-
以并行方式运行以下步骤:
-
让permissionState为 请求使用权限的结果,权限名称为"
notifications
"。 -
在全局任务队列中排队一个任务,任务源为DOM 操作任务源,目标为global, 以运行以下步骤:
-
-
返回promise。
通知是目前唯一一个向终端用户提前请求权限是合理的实例。其他 API 的规范不应使用此模式,而应采用 许多更合适的替代方案。
静态maxActions
获取器的步骤是返回
支持的最大操作数。
3.4. 对象成员
以下是 事件处理程序(及其对应的
事件处理程序事件类型),它们必须作为属性由
Notification
对象支持。
事件处理程序 | 事件处理程序事件类型 |
---|---|
onclick
| click
|
onshow
| show
|
onerror
| error
|
onclose
| close
|
navigate
获取器的步骤是:
image
获取器的步骤是:
icon
获取器的步骤是:
badge
获取器的步骤是:
vibrate
获取器的步骤是返回this的通知的振动模式。
timestamp
获取器的步骤是返回this的通知的时间戳。
renotify
获取器的步骤是返回this的通知的重新通知偏好。
requireInteraction
获取器的步骤是返回this的通知的需要交互偏好。
data
获取器的步骤是返回结构化反序列化(this的通知的数据, this的相关 Realm)的结果。如果此操作抛出异常,则返回 null。
actions
获取器的步骤是:
-
令 frozenActions 为一个类型为
NotificationAction
的空列表。 -
返回从frozenActions创建冻结数组的结果。
3.5. 示例
3.5.1. 在页面中使用事件
非持久性 Notification
对象在其生命周期内会分派事件,开发者可以利用这些事件来产生期望的行为。
当终端用户激活通知时,会分派 click
事件。
var not = new Notification("Gebrünn Gebrünn by Paul Kalkbrenner", { icon: "newsong.svg", tag: "song" }); not.onclick = function() { displaySong(this); };
3.5.2. 在 service worker 中使用操作
持久通知会在
ServiceWorkerGlobalScope
上触发
notificationclick
事件。
这里,一个 service worker 显示一个带单个“存档”通知操作的通知,允许终端用户从通知中执行这个常见任务,而无需打开网站(例如,通知平台可能会在通知上显示一个按钮)。终端用户也可以激活通知的主体来打开他们的收件箱。
self.registration.showNotification("来自 Alice 的新邮件", { actions: [{action: 'archive', title: "存档"}] }); self.addEventListener('notificationclick', function(event) { event.notification.close(); if (event.action === 'archive') { silentlyArchiveEmail(); } else { clients.openWindow("/inbox"); } }, false);
3.5.3. 为多个实例使用 tag
成员
Web 应用程序经常在多个实例中并发运行,例如当终端用户在多个浏览器标签页中打开一个邮件应用程序时。由于桌面是共享资源,通知 API 提供了一种让这些实例轻松协调的方式,即使用
tag
成员。
代表相同概念事件的通知可以用相同的标签标记,当两者都显示时,终端用户只会收到一个通知。
实例 1 | 实例 2 | // 实例注意到有新邮件。 | new Notification("来自 John Doe 的新邮件", | { tag: 'message1' }); | | | // 稍后,这个实例注意到 | // 有新邮件。 | new Notification("来自 John Doe 的新邮件", | { tag: 'message1' });
如果用户代理遵循此处的算法,这种情况的结果是一个通知“来自 John Doe 的新邮件”。
3.5.4. 为单个实例使用 tag
成员
tag
成员也可以被应用程序的单个实例用来随着状态变化尽可能保持其通知的最新状态。
例如,如果 Alice 正在与 Bob 使用聊天应用程序,而 Bob 在 Alice 空闲时发送了多条消息,应用程序可能希望 Alice 不会为每条消息都看到桌面通知。
// Bob 说“嗨” new Notification("Bob: 嗨", { tag: 'chat_Bob' }); // Bob 说“你今天下午有空吗?” new Notification("Bob: 嗨 / 你今天下午有空吗?", { tag: 'chat_Bob' });
这种情况的结果是一个通知;第二个通知替换了第一个具有相同标签的通知。在一个对通知进行排队(先进先出)的平台中,使用标签还允许通知保持其在队列中的位置。在最新通知最先显示的平台中,可以使用
close()
方法达到类似的结果。
4. Service Worker API
dictionary {
GetNotificationOptions DOMString = ""; };
tag partial interface ServiceWorkerRegistration {Promise <undefined >showNotification (DOMString ,
title optional NotificationOptions = {});
options Promise <sequence <Notification >>getNotifications (optional GetNotificationOptions = {}); }; [
filter Exposed =ServiceWorker ]interface :
NotificationEvent ExtendableEvent {(
constructor DOMString ,
type NotificationEventInit );
eventInitDict readonly attribute Notification notification ;readonly attribute DOMString action ; };dictionary :
NotificationEventInit ExtendableEventInit {required Notification ;
notification DOMString = ""; };
action partial interface ServiceWorkerGlobalScope {attribute EventHandler onnotificationclick ;attribute EventHandler onnotificationclose ; };
service worker 注册有一个关联的
是否已成功调用
showNotification()
(一个布尔值),初始值为
false。
这是 Push API 标准的基础设施。[PUSH-API]
showNotification(title, options)
方法的步骤是:
-
让 promise 为在this的相关 Realm中一个新的 promise。
-
让 notification 为使用设置对象创建通知的结果,给定 title、options 和this的相关设置对象。如果此操作抛出异常,则用该异常拒绝 promise 并返回 promise。
-
将 notification 的service worker 注册设置为 this。
-
并行运行以下步骤:
-
返回 promise。
getNotifications(filter)
方法的步骤是:
-
让 promise 为在 realm 中一个新的 promise。
-
并行运行以下步骤:
-
返回 promise。
此方法返回零个或多个新的Notification
对象,这些对象可能代表与已存在的Notification
对象相同的底层通知。
要触发一个 service worker 通知事件,名为
name,给定一个
通知
notification,以及一个可选字符串
action(默认为空字符串):运行触发功能性事件,给定 name、NotificationEvent
、
notification 的service worker 注册,以及以下初始化:
notification
- 一个代表 notification 的新
Notification
对象。 action
- action
notification
获取器的步骤是返回其初始化时的值。
action
获取器的步骤是返回其初始化时的值。
以下是必须由
ServiceWorkerGlobalScope
对象作为属性支持的事件处理程序(及其对应的
事件处理程序事件类型):
事件处理程序 | 事件处理程序事件类型 |
---|---|
onnotificationclick
| notificationclick
|
onnotificationclose
| notificationclose
|
致谢
感谢 Addison Phillips、 Aharon (Vladimir) Lanin、 Alex Russell、 Anssi Kostiainen、 Arkadiusz Michalski、 Boris Zbarsky、 Brady Eidson、 David Håsäther、 Doug Turner、 Drew Wilson、 Ehsan Akhgari、 Frederick Hirsch、 Ian Hickson、 Jake Archibald、 James Graham、 John Mellor、 Jon Lee、 Jonas Sicking、 Kagami Sascha Rosylight、 Michael Cooper、 Michael Henretty、 Michael™ Smith、 Michael van Ouwerkerk、 Mike Taylor、 Nicolás Satragno、 Olli Pettay、 Peter Beverloo、 Philip Jägenstedt、 Reuben Morais、 Rich Tibbett、 Robert Bindar、 박상현 (Sanghyun Park)、 Simon Pieters、 Theresa O’Connor、 timeless,以及 triple-underscore 的杰出贡献。
本标准由 Anne van Kesteren (Apple, annevk@annevk.nl) 撰写。 早期版本由 John Gregg (Google, johnnyg@google.com) 撰写。
知识产权
版权所有 © WHATWG (Apple, Google, Mozilla, Microsoft)。本作品根据 知识共享署名 4.0 国际许可协议授权。如果其部分内容被纳入源代码,则源代码中的这些部分将根据 BSD 3-Clause 许可证授权。
这是现行标准。对专利审查版本感兴趣的人应查看 现行标准审查草案。