浏览器通知 Notification API 的研究

1,276 阅读5分钟

1.前言

H5 提供了一个 Notification API 用于处理桌面浏览器的消息通知。 这个 api 实现的通知是脱离浏览器的,即使用户没有停留在当前标签页,甚至最小化了浏览器,该通知信息也一样会置顶显示出来,这样即使应用程序空闲或在后台也可以向用户发送信息。

2.实现

一个桌面通知生成的正常流程:

  1. 检查浏览器是否支持Notification
  2. 检查浏览器的通知权限(是否允许通知)
  3. 若权限不够则获取浏览器的通知权限
  4. 创建消息通知
  5. 展示消息通知

Notifications 的诞生简化了网站或者应用与用户之间的沟通成本,同时也具有它的局限性,无法存档、即看即毁。

3.使用

3.1 创建对象

var notification = new Notification(title, [options])

参数

参数 类型 描述
title string 显示的通知标题
[options] object 显示通知的配置项,可选
[options.dir] string 文字方向, 取值为 auto、ltr、rtl 之一
[options.lang] string 通知的语言,这个字符串必须在 BCP 47 language tag 文档中是有效的。
[options.body] string 通知的内容
[options.tag] string 通知的 id,通过此 id 可以对通知进行刷新、替换或移除
[options.icon] string 通知的图标图片URL,将被用于显示通知的图标。

options 参数

{
    //通知显示正文。非必须,默认为空
    body: '你的好友XX上线了!',
    //通知显示正文的图片地址。非必须,默认为空
    image: 'imgae url',
    //通知左侧图标。非必须,默认为空
    icon: 'imgae url',
    //通知的分类标记(ID)。非必须,默认为空
    tag: 'test',
    //通知相关联的数据,通常用于方法的回调,传参。非必须,默认为空
    data: '可以是任意数据类型',
    //通知显示延迟的时间。非必须,默认通知实例创建完成就显示
    timestamp: '',
    //通知主体内容的水平展示顺序,有点类似direction属性。非必须,默认值是auto, 可以是ltr或rtl
    dir: 'auto',
    //当没有足够的空间来显示通知本身时,用于表示通知的图像的URL。非必须,默认为空
    badge: 'xxx',
    //通知的语言。非必须默认为空
    lang: '',
    //通知显示时,设备的振动模式。非必须,默认为空
    vibrate: [200, 100, 200],
    //新通知出现是否覆盖旧的通知,覆盖(true)则永远只显示一条通知,不覆盖(false)则会多条通知重叠。非必须,默认为true
    renotify: true,
    //通知是否静音。非必须,默认为false,表示无声
    silent: false,
    //通知声源文件地址。非必须,默认为空
    sound: 'mp3',
    //是否不在屏幕上显示通知信息。非必须,默认为false表示要显示
    noscreen: false,
    //指定通知是否应该粘滞性,即不容易被用户清理。非必须,默认false表示不具粘滞性
    sticky: false,
    //指定通知是否保持活性,直到用户点击或关闭。非必须,默认为false
    requireInteraction: false
}

3.2 通知权限

Notification.permission 是一个静态方法,可以获取用户当前的通知权限状态,返回一个String,可以根据返回值判断用户是否授予了通知权限。

返回值有三种情况:

  • default 用户还未被询问是否授权,所以通知不会被显示。
  • granted 表示之前已经询问过用户,并且用户已经授予了显示通知的权限。
  • denied 用户已经明确的拒绝了显示通知的权限。

当值为default或者denied时都不会显示通知消息,只有明确的被设置成granted才会显示通知消息

const permission = Notification.permission;
if(permission === 'granted'){
    console.log('已经授权通知,可以进行你的通知啦!');
}else if (Notification.permission === 'default') {
    console.log('用户还未选择同意/拒绝');
    // 下一步请求用户授权
} else {
    console.log('用户曾经拒绝授权,不能显示通知');
}

3.3 请求权限

应用发送通知之前必须要取得发送通知的权限,才能成功进行通知。 Notification.requestPermission(CALLBACK)是请求获取权限的方法,允许传入一个回调,回调会返回用户选择的何种权限,返回两个值,granted 代表允许,denied代表拒绝。

Notification.requestPermission() 支持then方式的链式调用,也就意味着可以异步调用它。

//方式一,老版是回调函数机制
Notification.requestPermission(function (permission) {
    if (permission === 'granted') {
    	console.log('用户同意授权');
     	// 随时可以显示通知
  	} else if (permission === 'default') {
    	console.log('用户关闭授权,可以再次请求授权');
  	} else {
    	console.log('用户拒绝授权,不能显示通知');
  	}
});

//方式二,通过then回调,两种方式是等价的
Notification.requestPermission().then(function (permission) {
   if (permission === 'granted') {
    	console.log('用户同意授权');
     	// 随时可以显示通知
  	} else if (permission === 'default') {
    	console.log('用户关闭授权,可以再次请求授权');
  	} else {
    	console.log('用户拒绝授权,不能显示通知');
  	}
});

4.事件

通知生成后会返回一个实例:

var instanceNotification = new Notification(title, options)

当通知被创建成功后:

  1. 通知实例具有一个静态方法可以用来关闭通知
  2. 读取相关的配置
  3. 通知实例具有四个事件钩子,来跟踪通知当前的状态。

4.1 关闭通知

instanceNotification.close()

4.2 事件处理

通知实例具有四个事件钩子,来跟踪通知当前的状态。 这些事件可以通过事件处理跟踪onshowonclickoncloseonerror。 因为 Notification 同样继承自 EventTarget,因此可以对它调用addEventListener()方法。

我们可以使用通知的实例来监听通知的事件:

  • onclick: 用户点击通知时被触发
  • onshow: 通知显示的时候被触发
  • onerror: 通知遇到错误时被触发
  • onclose: 用户关闭通知时被触发

注意:最好是一发出通知就立即监听事件,否则有些事件可能一开始没被触发或永远不会触发。

5.iNotify库

iNotify 库对 Notification API 做了封装。只需要做简单的配置就可以直接使用,配置简单,项目中如果有需要,建议使用该库。