1. 术语
本规范依赖于 Infra 标准。[INFRA]
本规范中使用的一些术语在 DOM、Fetch、高分辨率时间、HTML、IDL、服务工作者、URL 和振动 API 标准中定义。[DOM] [FETCH] [HR-TIME] [HTML] [WEBIDL] [SERVICE-WORKERS] [URL] [VIBRATION]
2. 通知
一个通知是已发生事件的抽象表示,例如消息的传递。
一个通知具有一个关联的服务工作线程注册(null 或一个服务工作线程注册)。它最初为 null。
一个通知具有一个关联的标题(一个字符串)。
一个通知具有一个关联的方向(“auto
”、“ltr
”或“rtl
”)。
一个通知具有一个关联的语言(一个字符串)。
一个通知具有一个关联的正文(一个字符串)。
一个通知具有一个关联的标签(一个字符串)。
一个通知具有一个关联的时间戳(一个EpochTimeStamp
)。
时间戳可用于指示通知的实际时间。例如,当通知用于因设备离线而无法立即传递的消息时,这可能是在过去,或者对于即将开始的会议,这可能是在将来。
一个通知具有一个关联的重新通知偏好(一个布尔值)。它最初为 false。当为 true 时,表示在通知显示步骤已运行且新通知与现有通知具有相同的标签后,应提醒最终用户。
一个通知具有一个关联的静默偏好(null 或一个布尔值)。它最初为 null。当为 true 时,表示不应发出声音或振动。当为 null 时,表示应根据平台约定来决定是否产生声音或振动。
一个通知具有一个关联的需要交互偏好(一个布尔值)。它最初为 false。当为 true 时,表示在具有足够大屏幕的设备上,通知应保持随时可用,直到最终用户激活或关闭通知。
一个通知可以具有这些关联的图形:一个图像 URL、图标 URL和徽章 URL;以及它们对应的图像资源、图标资源和徽章资源。
一个图像资源是作为通知内容一部分显示的图片,并且应以比图标资源和徽章资源更高的视觉优先级显示,尽管它可能在较少的情况下显示。
一个图标资源是强化通知的图像(例如图标或发送者的照片)。
一个徽章资源是代表 Web 应用程序的图标,或者如果 Web 应用程序发送各种通知,则代表通知的类别。当没有足够空间显示通知本身时,它可以用于代表通知。它也可能显示在通知内部,但那样它的视觉优先级应低于图像资源和图标资源。
一个通知具有一个关联的振动模式(一个列表)。它最初为 « »。
鼓励开发人员不要通过图像、图标、徽章或振动模式传递最终用户无法以其他方式访问的信息,特别是因为不支持这些功能的通知平台可能会忽略它们。
一个通知具有关联的操作(一个包含零个或多个通知操作的列表)。一个通知操作代表最终用户的一个选择。每个通知操作都有一个关联的:
- 名称
- 一个字符串。
- 标题
- 一个字符串。
- 图标 URL
- Null 或一个URL。它最初为 null。
- 图标资源
- Null 或一个资源。它最初为 null。
用户可以激活操作,作为激活通知本身的替代方案。支持的最大操作数是一个实现定义的零个或多个整数,在通知平台的约束范围内。
由于操作的显示取决于平台,因此鼓励开发人员确保最终用户可以从通知中调用的任何操作在 Web 应用程序中也可用。
某些平台可能会在向最终用户显示图标资源之前对其进行修改以更好地匹配平台的视觉样式,例如通过圆角处理或将其绘制成特定颜色。鼓励开发人员使用能够优雅处理此类情况并且不会因例如颜色丢失或边角裁剪而丢失重要信息的图标。
一个非持久性通知是一个通知,其服务工作线程注册为 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["
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. 生命周期和UI集成
用户代理必须保留一个通知列表,它是一个包含零个或多个通知的列表。
用户代理不应在平台的“通知中心”(如果可用)中显示非持久性通知。
一个持久性通知可以调用其某个Notification
对象的close()
方法。
用户代理应在平台的“通知中心”(如果可用)中显示持久性通知。
2.2. 权限集成
通知 API 是一个强大的功能,由名称“notifications
”标识。[权限]
要获取通知权限状态,请执行以下步骤:
-
令 permissionState 为使用“
notifications
”获取当前权限状态的结果。 -
如果 permissionState 是“
prompt
”,则返回“default
”。 -
返回 permissionState。
2.3. 方向
本节内容的术语与HTML渲染部分中使用的术语等效。[HTML]
用户代理应遵循通知的标题、正文以及其每个操作的标题文本的 Unicode 语义。在显示时,每个文本都应被视为一个或多个独立的双向算法段落,如双向算法规则 P1、P2 和 P3
所定义,例如,包括支持 U+000A 换行符 (LF) 字符的段落分隔行为。对于标题、正文以及每个操作的标题的每个段落,如果通知的方向具有非“auto
”的值,则它将提供对规则 P2 和
P3 的更高级别覆盖。[BIDI]
通知的方向还决定了如果通知平台并排显示通知的操作,则应向最终用户显示这些操作的相对顺序。
2.4. 语言
通知的语言指定了通知的标题、正文以及其每个操作的标题的主要语言。其值是一个字符串。空字符串表示主要语言未知。任何其他字符串都必须解释为语言标签。不强制执行有效性或格式正确性。[BCP47]
建议开发者只使用有效的语言标签。
2.5. 资源
给定通知 notification 的获取步骤如下:
-
如果通知平台支持图像,并且设置了图像 URL,则获取notification的图像 URL。
目的是像获取
<img>
资源一样获取此资源,但这需要抽象化。然后,并行地:
-
如果通知平台支持图标,并且设置了图标 URL,则获取notification的图标 URL。
目的是像获取
<img>
资源一样获取此资源,但这需要抽象化。然后,并行地:
-
如果通知平台支持徽章,并且设置了徽章 URL,则获取notification的徽章 URL。
目的是像获取
<img>
资源一样获取此资源,但这需要抽象化。然后,并行地:
-
如果通知平台支持操作和操作图标,则对于 notification 的操作中的每个 action:如果图标 URL非 null,则获取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 或其操作之一时,假设底层通知平台支持激活,则用户代理必须(除非另有说明)运行以下步骤:
-
如果 notification 是一个持久性通知,则:
-
令 action 为空字符串。
- 给定 notification 和 action,触发一个名为“
notificationclick
”的服务工作线程通知事件。
-
-
否则,将一个任务排队以运行以下步骤:
-
令 intoFocus 为在代表 notification 的
Notification
对象上触发一个名为click
的事件的结果,其cancelable
属性初始化为 true。鼓励用户代理使
focus()
在名为click
的事件的事件侦听器内工作。 -
如果 intoFocus 为 true,则用户代理应将 notification 的相关浏览上下文的视口置于焦点。
-
在整个 Web 平台中,“激活”被有意地错误命名为“点击”。
2.8. 关闭通知
当通知被底层通知平台或最终用户关闭时,必须为其运行关闭步骤。
给定通知 notification 的关闭步骤如下:
要处理关闭事件,给定一个通知 notification:
-
如果 notification 是一个持久性通知并且 notification 是由最终用户关闭的,则给定 notification 触发一个名为“
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 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 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 ; };
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
getter 步骤是返回获取通知权限状态的结果。
如果您编辑标准,请不要复制以上内容。同步权限类似于同步 IO,是一个坏主意。
鼓励开发人员改用 Permissions query()
方法。[权限]
const permission = await navigator.permissions.query({name: "notifications"}); if (permission.state === "granted") { // 我们有权使用 API… }
静态 requestPermission(deprecatedCallback)
方法步骤如下:
通知是目前为止唯一一个在请求用户权限时有意义的实例。其他API的规范不应使用这种模式,而应采用更多合适的替代方案之一。
静态maxActions
获取器步骤是返回支持的最大操作数。
3.4. 对象成员
以下是 事件处理器(及其对应的 事件处理器事件类型),必须作为 Notification
对象的属性支持。
事件处理器 | 事件处理器事件类型 |
---|---|
onclick
| click
|
onshow
| show
|
onerror
| error
|
onclose
| close
|
image
getter 步骤如下:
icon
getter 步骤如下:
badge
getter 步骤如下:
vibrate
getter 步骤是返回此的通知的
振动模式。
timestamp
getter 步骤是返回此的通知的
时间戳。
renotify
getter 步骤是返回此的通知的
重新通知偏好。
silent
getter 步骤是返回此的通知的
静默偏好。
requireInteraction
getter 步骤是返回此的通知的
需要交互偏好。
data
getter 步骤是返回StructuredDeserialize(此的通知的数据, 此的相关 Realm)。如果此操作引发异常,则返回 null。
actions
getter 步骤如下:
-
令 frozenActions 为一个类型为
NotificationAction
的空列表。 -
-
令 action 为一个新的
NotificationAction
。 -
如果 entry 的图标 URL 非 null,则将 action["
icon
"] 设置为 entry 的图标 URL,并进行序列化。 -
在 action 上调用 Object.freeze,以防止脚本意外修改。
-
将 action 追加到 frozenActions。
-
-
返回从 frozenActions 创建冻结数组的结果。
3.5. Examples
3.5.1. Using events from a page
非持久化 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. Using actions from a service worker
持久化通知 在
ServiceWorkerGlobalScope
上触发 notificationclick
事件。
此处,服务工作线程显示一个带有单个“存档”通知操作的通知,允许最终用户直接从通知执行此常见任务,而无需打开网站(例如,通知平台可能会在通知上显示一个按钮)。最终用户还可以激活通知的主体以打开其收件箱。
self.registration.showNotification("New mail from Alice", { actions: [{action: 'archive', title: "Archive"}] }); 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("New mail from John Doe", | { tag: 'message1' }); | | | // 稍后,此实例注意到有新邮件。 | new Notification("New mail from John Doe", | { tag: 'message1' });
如果用户代理遵循此处的算法,这种情况下的结果是一个 单一 通知 "来自 John Doe 的新邮件"。
3.5.4. 使用 tag
成员来处理单个实例
tag
成员还可以由单个实例的应用程序使用,以便在状态更改时保持其通知尽可能最新。
例如,如果 Alice 正在使用聊天应用程序与 Bob 聊天,而 Bob 在 Alice 闲置时发送了多条消息,应用程序可能希望 Alice 不会看到每条消息的桌面通知。
// Bob 说 "Hi" new Notification("Bob: Hi", { tag: 'chat_Bob' }); // Bob 说 "你今天下午有空吗?" new Notification("Bob: Hi / 你今天下午有空吗?", { 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 ; };
showNotification(title, options)
方法步骤如下:
-
令 notification 为给定 title、options 和此的相关设置对象使用设置对象创建通知的结果。如果此操作引发异常,则用该异常拒绝 promise 并返回 promise。
-
并行运行以下步骤:
-
返回 promise。
getNotifications(filter)
方法步骤如下:
此方法返回零个或多个新的 Notification
对象,这些对象可能代表已存在的 Notification
对象的相同底层通知。
要触发服务工作线程通知事件(名为 name),给定一个通知
notification,以及一个可选字符串 action(默认为空字符串):运行触发功能事件,给定 name、NotificationEvent
、notification
的服务工作线程注册以及以下初始化:
notification
- 一个代表 notification 的新
Notification
对象。 action
- action
notification
getter 步骤是返回其初始化时的值。
action
getter 步骤是返回其初始化时的值。
以下是事件处理程序(以及其对应的事件处理程序事件类型),ServiceWorkerGlobalScope
对象必须将其作为属性支持:
事件处理器 | 事件类型 |
---|---|
onnotificationclick
|
notificationclick |
onnotificationclose
|
notificationclose |
致谢
感谢 Addison Phillips, Aharon (Vladimir) Lanin, Alex Russell, Anssi Kostiainen, Arkadiusz Michalski, Boris Zbarsky, David Håsäther, Doug Turner, Drew Wilson, Ehsan Akhgari, Frederick Hirsch, Ian Hickson, Jake Archibald, James Graham, John Mellor, Jon Lee, Jonas Sicking, 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, and triple-underscore for being awesome.
本标准由 Anne van Kesteren (Apple, annevk@annevk.nl) 撰写。早期版本由 John Gregg (Google, johnnyg@google.com) 撰写。
知识产权
版权所有 © WHATWG (Apple, Google, Mozilla, Microsoft)。本作品采用 知识共享署名 4.0 国际许可协议 授权。若本作品的部分内容被纳入源代码中,则该部分内容在源代码中依据 BSD 3-Clause License 授权。
这是现行标准。对于专利审查版本感兴趣的人员,应查看 现行标准 审查草案。