发布日期 » 2017年7月11日 星期二

版权声明 » 帅华君原创文章,未经允许不得转载。

Javascript Web Notification API 译文

Advertisement :)

Web Notification API 英文原文地址

摘要

Web Notifications 定义了一个作用于用户终端的通知API,这个通知允许在某个事件发生后在用户所在网页上下文的外部出现一则警告讯息,比如提示用户收到了一封邮件。

目录

  • 介绍
  • 约定
  • 术语
  • 模型
  • API
  • 例子

介绍

这个规范提供了一个能够在用户所访问的网页的上下文之外显示一则警告讯息。这个规范规定将通知显示在“Desktop”,通常来说指的是网页外部的静态显示区域,通常有如下几种表现形式,包括:

  • 用户视线范围一角
  • 用户代理浏览器chrome之内
  • 移动设备的“home”屏幕

规范并没有特别详尽的说明用户代理应该如何显示这些通知;因此最佳的应用形式取决于用户代理所运行的设备。这套规范中的关于展现形式的选项使得他非常的灵活。

这套规范被设计出来作为一种尽可能完善的兼容已存在的各个平台处理通知消息的web解决方案,但是它也是依赖于平台的。即便各个平台没有提供一套普适的属性、方法和功能,但是这套规范也会明确的告知开发者哪些被允许使用哪些不被允许使用。值得一提的是,所有平台的通知消息的共同功能是都可以包含文本内容和图标。

通常来讲,事件模型在很大程度上让消息通知功能变得很容易。当 Notification 对象被设置了一个 click 事件,应用程序可以通过监听这一 click 事件增强应用的功能性,但是不能如此依赖接收事件的机制,以防各种平台的底层实现并没有对通知提供这一能力。

模型

一个 notification 允许在网页的外部给予用户一则警告,提示发生了什么事情,比如邮件的收发。

每一个notification都有title,language,和origin

每一个notification相关的body,tag,icon,URL,和icon图片

提示:不鼓励开发者过多的依赖于通过图标、声音和震动模式来传递信息,因为可能这些功能对一些终端用户并不起作用。

4.1 方向

4.2 语言

4.3 权限

只有当用户或着用户代理被授予显示通知的权限后通知消息才会被显示。最终开发者被返回的权限收于结果会是如下三个字符串之一:

default

这一标志等价于denied,只是用户并没有明确的表示拒绝,这只是默认的权限状态。

拒绝

这意味着用户不希望看到通知。

授予

这意味着通知可以被显示。(“granted”并不等价于“default”,这种情况下“granted”简单的被返回,之后将不在询问权限。)

4.4 通过列表

用户代理必须保存所有所有待定的通知列表和所有活动中的通知列表,当待显示的通知不为空且显示通知的区域有空余位置时,需要将待显示的通知显示出来。

4.5 显示一条通知

一条通知的显示步骤如下:

1.如果针对当前通知的 origin 是不被允许的权限,那么取消全部正在进行中的通知的图标URL,并抛出一个异常,并终止这一步骤。

2.如果这个通知位于正在待显示的通知列表内或激活中的通知列表内,并且tag等于通知的tag,并且origin等于通知的origin,那么为通知执行替换步骤,之后终止这一步骤。

3.如果当前设备允许该通知在众多通知中被立即显示出来,那么执行显示步骤,之后终止这一步骤。

4.如果设备对并发通知有限制,那么会立即将通知传送给平台原生的队列中,或者将通知添加到待通知的通知列表内。

4.5 激活一条通知

当一条通知是活动的状态,假设底层通知平台支持活动,用户代理必须将每一个Notification对象触发一个事件命名为click

自始至终web平台故意错误的命名activateclick

User agents are strongly encouraged to make window.focus() work from within the event listener for the event named click as a means of focusing the browsing context related to the notification.

4.7关闭一个通知

当一个通知是关闭的状态,不论是底层通知平台亦或是经用户之手,关闭的步骤永远是起作用的。

关闭的步骤如下:

1.如果通知既不在待通知的列表内,也不在活动中的通知列表内,则终止这些步骤。
2.将移除通知放入任务队列不论是对于待通知还是活动中的通知,并且在通知上触发一个叫做close的事件。

4.8待定的通知

无论待通知列表是不是空的状态。用户代理必须等待并且模拟器需要改变设备上可用的通知显示空间。

当设备上可用的显示通知的空间改变后,那么一个新的通知将会被显示出来。举个例子,由于之前一个通知的移除,用户代理应该对待通知的通知列表的第一个通知执行display steps显示步骤,并且将其从待通知的列表中移除。

4.9显示中的通知

显示步骤如下:

1.如果通知平台支持显示图标,通知的图标地址被设置了并且还没有被获取,那么获取该图标地址并且等待图标资源被完全下载下来。一旦获取才做已经完成并且如果图片格式也是被支持的,则将解码后的资源设置到通知的图标上。

2.将如下子步骤加入任务队列:
(1)在设备上显示通知(设备自行通过适当的显示方式执行API)
(2)如果显示失败(通知平台返回一个错误),则在notification上触发一个名为error的事件,之后终止这一步骤。
(3)将通知推送到待通知的列表内。
(4)触发一个名为show的通知事件。

4.10替换一个通知

替换的步骤,也就是新的通知替换旧有的通知的步骤如下:
1.如果通知平台只是图标,新的通知的图标属性被用户设置了但是还没有获取图标资源,那么获取他并且等待资源被完全下载下来。

一旦图标资源被成功获取到并且图片的格式也是被支持的,那么就设置解码后的图标图片。

2.如果旧有的通知存在于待通知列表或任务队列内,那么触发close事件。

3.否则,将替换旧有的通知放入任务队列中,并放入待通知列表内的相同位置,在旧有的通知对象上触发close事件,并且在新添加的事件触发名为show的事件。

如果通知平台不支持替换,那么该请求将会被实现为对旧有的通知实现close steps关闭步骤之后对新添加的通知执行display step显示步骤。

通知平台强烈建议支持原生的替换实现,这很棒。Notification platforms are strongly encouraged to support native replacement. It is much nicer.


API

一则通知被表示为一个Notification对象并且可以被它的构造器创建。

[Constructor(DOMString title, optional NotificationOptions options)]
interface Notification : EventTarget {
  static readonly attribute NotificationPermission permission;
  static void requestPermission(optional NotificationPermissionCallback callback);

  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 DOMString icon;

  void close();
};

dictionary NotificationOptions {
  NotificationDirection dir = "auto";
  DOMString lang = "";
  DOMString body;
  DOMString tag;
  DOMString icon;
};

enum NotificationPermission {
  "default",
  "denied",
  "granted"
};

callback NotificationPermissionCallback = void (NotificationPermission permission);

enum NotificationDirection {
  "auto",
  "ltr",
  "rtl"
};

Notification(title, options) 构造器必须执行这些步骤:

1.实例化一个Notification对象。

2.设置通知的title属性。

3.设置通知的des选项。

4.如果选项的lang属性是可用的BCP 47语言标签,或者空的字符串,设置通知的语言到选项的lang,否则,设置为空的字符串。

5.设置通知的origin为当前的origin

6.如果选项的body出现,那么设置通知的body

7.如果选项的tag出现,那么设置通知的tag

8.如果选项的icon出现,解析使用API base URL来解析icon资源,并且如果没有返回错误信息,那么将解析后的至赋给图标地址。

9.返回通知实例,但是继续异步的执行下面的步骤。

10.如果图标地址被设置了并切通知平台支持多个图标,此刻用户代理可以开始从用用户提供的图标路径获取图标资源。

11.对通知执行show steps

静态的permission属性必须返回许可。

静态的**requestPermission(callback)**方法必须执行以下步骤:

1.返回并且继续异步的执行这些步骤。

2.生命permissionpermission

3.如果返回的permissiondefault,询问用户能否接受在当前的域中显示通知。如果用户做出了某个决定,将permission设置为granted或者denied

4.将设置permission放入任务队列,调用回调函数,并将权限申请结果作为参数传入传给回调函数。

下列事件处理器需要被Notification支持:

事件处理器 事件类型
onclick click
onshow show
onerror error
onclose close

close()方法必须执行close steps

title属性必须返回通知的title

dir属性必须返回通知的direction

lang属性必须返回通知的language

body属性必须返回通知的body或者一个空的字符串。

tag标签必须返回通知的tag或者如果没有标签则返回一个空的字符串。

icon属性必须返回一个通知的icon URL,序列化,或者空的字符串。


例子

6.1使用事件

Notification对象在其生命周期内奋发时间,开发者可以使用其这一特性来部署特殊的行为。

当通知展示给用户之后show事件就会被分发,有时也会在通知被创建后或者被加入任务队列后触发。

在下面的例子中,通知将被现实15秒。

var notification = new Notification("New Email Received", { icon: "mail.png" })
notification.onshow = function() { setTimeout(notification.close, 15000) }

当通知被用户接触时close事件被触发,开发者可以使用这个事件去执行任务,因为这个时间的触发意味着用户已经看到了通知并关闭了它。

下面这个例子,当用户被通知后,这个应用会取消其后的所有待提醒的通知。

var notification = new Notification("Meeting about to begin", { icon: "calendar.gif", body: "Room 101" })
notification.onclose = function(event) { cancelReminders(event) }

6.3为单一的实例使用tag属性

tag属性能够用于应用的单一实例,以确保改变状态的为当前的通知。

举个例子,如果Alice和Bob在使用一个聊天应用,这时候Bob发送了多条讯息,并且Alice没有注意到。应用可以推测到Alice没有看到任何一套通知。

// Bob says "Hi"
new Notification("Bob: Hi", { tag: 'chat_Bob' });

// Bob says "Are you free this afternoon?"
new Notification("Bob: Hi / Are you free this afternoon?", { tag: 'chat_Bob' });

出现这种情景的结果就是一个单一的通知,第二个替换了第一个拥有相同标签的通知,使用标签的好处就是确保通知依然保持在他当前的位置,足心的通知第一个显示,相似的结果也能通过**close()**实现。

参考

[BID] Unicode Bidirectional Algorithm,Mark Davis. Unicode Consortium.

[DOM4] DOM, Anne van Kesteren, Aryeh Gregor, Ms2ger et al… W3C.

[HTML5] HTML5, Robin Berjon, Steve Faulkner, Travis Leithead et al… W3C.

[LANG] Tags for Identifying Languages; Matching of Language Tags,Addison Phillips and Mark Davis. IETF.

[RFC2119] Key words for use in RFCs to Indicate Requirement Levels,Scott Bradner. IETF.

[URL] URL,Eric Arvidsson, Michael[tm] Smith. W3C.

[WEBIDL] Web IDL,Cameron McCormack. W3C.