Javascript Notifications API

Notifications API 允许网页或应用程序发送通知,这些通知在系统级显示在网页之外; 这使得网页应用程序可以向用户发送信息,即使应用程序处于空闲状态或在后台,一般搭配 websocket 使用。

安全上下文: 此特性仅在安全上下文(HTTPS)中可用,在部分或所有支持的浏览器中都可用。

需要注意的是此 API 只有在 https 的网页中才有效果,但是经过我的测试发现在 Firefox 浏览器中貌似本地也可以调试,但是 Chrome本地开发环境下确实不行。那么如果非要想在 Chrome 浏览器的本地开发环境下调试应该怎么办呢?我查了好久也终于找到了相应的解决方案:

在 HTTP 网站中开启 Notification API

请求权限

在应用可以发送通知之前,用户必须授予应用有权这么做。这是一个常见的要求,当一个 API 至少一次试图与 web 页外部进行交互时,用户不得不专门授予该应用程序有权限提出通知,从而让用户控制允许哪些应用程序或网站显示通知。

权限状态有以下三种:

  • default:用户还未被询问是否授权,所以通知不会被显示。参看 获得权限 以了解如何请求显示通知的权限。

  • granted:表示之前已经询问过用户,并且用户已经授予了显示通知的权限。

  • denied:用户已经明确的拒绝了显示通知的权限。

如果权限尚未被授予,那么应用不得不通过 Notification.requestPermission() 方法让用户进行选择。这个方法接受一个回调函数,一旦用户回应了显示通知的请求,将会调用这个函数。

通常你应在你的应用首次初始化的时候请求显示通知的权限:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
checkPermission(onSuccess?: Function, onError?: Function, onThen?: Function) {
if (this.permissionLevel !== 'granted') {
if (!this.isSupported) {
return;
}
Notification.requestPermission(result => {
if (result === 'granted') {
this.permissionLevel = 'granted';
if (onSuccess) {
onSuccess();
}
} else if (result === 'denied') {
this.permissionLevel = 'denied';
if (onError) {
onError();
}
} else {
this.isSetPermission = false;
}
});
} else {
this.permissionLevel = 'granted';
if (onSuccess) {
onSuccess();
}
}
this.isSetPermission = true;
if (onThen) {
onThen();
}
}

创建通知

创建通知很简单,只需要用 Notification 构造方法。这个构造函数需要一个用来显示在通知内的标题以及一些用来增强通知的选项,例如 icon 或文本 body。

一旦通知被创建出来,它会立即被显示出来。为了跟踪通知当前的状态,在 Notification 实例层面上会有 4 个事件被触发:

  • show:当通知被显示给用户时触发。
  • click:当用户点击通知时触发。
  • close:当通知被关闭时触发。
  • error:当通知发生错误的时候触发。这通常是因为通知由于某些原因而无法显示。

这些事件可以通过事件处理跟踪 onshow、onclick、onclose 和 onerror。因为 Notification 同样继承自 EventTarget,因此可以对它调用 addEventListener() 方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
show(option: { title?: string; body?: string; icon?: string, click?: Function }) {
if (this.isSupported) {
const notifyOption = Object.assign({}, this.configOptions, option);
if (this.permissionLevel === 'granted') {
const notification = new Notification(notifyOption.title, notifyOption);
if (option.click) {
notification.onclick = () => {
option.click();
notification.close();
};
}
} else {
Notification.requestPermission(result => {
if (result === 'granted') {
const notification = new Notification(notifyOption.title, notifyOption);
if (option.click) {
notification.onclick = () => {
option.click();
notification.close();
};
}
}
});
}
}
}

关闭通知

可以使用 close ()删除与用户不再相关的通知。