HTML Notification 了解与实践

375 阅读5分钟

很久以前,做了个小需求,关于浏览器通知。用户在点击提交订单之后 后台管理系统需要在浏览器端显示用户订单通知消息,于是整理了部分关于H5 Notification。

远古实现 浏览器通知

long long ago 传统通知一般都是使用定时器不断的修改 document.title 的值, 以达到浏览器通知效果, 例如。

let isNewNotice = true

setInterval(()=>{
  const _title = document.title
  if(isNewNotice){

    if(!/新消息/.test(_title)) document.title = '【你有新消息】'
    else document.title = '【     】'

  }else document.title = _title
}, 500)

效果

1.gif

然而这种提示有致命的缺陷,就是需要用户一直打开浏览器,并且时刻关注title部分是否有变化,于是HTML Notification就诞生了

HTML5 Web Notification

Notifications API 允许网页或应用程序在系统级别发送在页面外部显示的通知;这样即使应用程序空闲或在后台,Web 应用程序也会向用户发送信息。

总体兼容性

2.png

各API兼容性

点击展开查看兼容性

image.png

image.png

看到这么密密麻麻的兼容性,很容易让人望而却步,所以这里笔者整理出一份常用API以及日常我们(不考虑IE浏览器)可行方案,供大家参考

常用API

1. Notification.permission 用户权限

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

  • granted: 用户已经明确的授予了显示通知的权限

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

  • default: 用户还未被询问是否授权; 这种情况下权限将视为 denied

2. Notification.requestPermission 请求用户权限

在给用户发送通知的时候必须要请求用户通知权限,才能给用户发送通知。 这里 Notification.requestPermission 可以使用回调函数,也可以使用promise方式,具体如下

// 旧 已废弃 Gecko 46, 但是仍然可用
Notification.requestPermission(function (permission) {
    console.log(`允许通知${permission === 'granted' ? '允许' : '拒绝'}`);
});
// 新
Notification.requestPermission().then((permission) => {
    console.log(`允许通知${permission === 'granted' ? '允许' : '拒绝'}`);
}
3. new Notification(title,options) 创建通知

通过new 构造,title是必须参数,表示通知小框框的标题内容,options对象是可选参数,常用支持参数以及说明如下。

属性名值(说明)
dir文字的方向;它的值可以是 auto(自动), ltr(从左到右), 或者 rtl(从右到左)
lang指定通知中所使用的语言。这个字符串必须在 BCP 47 language tag 文档中是有效的,(没多大用)
body通知中额外显示的字符串(提示的主题内容)
tag赋予通知一个ID,以便在必要的时候对通知进行刷新、替换或移除,尽量保持唯一性
icon一个图片的URL,将被用于显示通知的图标,不支持.ico
data任意类型和通知相关联的数据, 可以放在实例中使用
vibrate通知显示时候,设备震动硬件需要的振动模式。所谓振动模式,指的是一个描述交替时间的数组,分别表示振动和不振动的毫秒数,一直交替下去。例如[200, 100, 200]表示设备振动200毫秒,然后停止100毫秒,再振动200毫秒。(PC端不考虑)
renotifyrenotifyNotification 接口的只读属性,如果有新的通知替换了一个旧的通知,这个属性指明用户是否应该重新收到通知。默认为false(大多浏览器表现形式是叠楼层),设为true时候就是替换
silent一个布尔值,false是默认值;true使通知静音。具体声音跟随浏览器默认声音。以及在PC端是否起作用跟随浏览器型号和版本。
sound字符串。音频地址。表示通知出现要播放的声音资源。(存在极大兼容性,有些浏览器不生效)
sticky布尔值。是否通知具有粘性,这样用户不太容易清除通知。默认false, 表示没有粘性。
4. 实例notification.close()

Notification 实例的 close() 的方法用于关闭一个以前显示的通知。如果没有调用关闭方法,chrome和safari 会在5秒左右自动关闭。notification没有定时控制通知多久后消失的功能,当出现多个通知,也无法统一关闭,弹窗无法设置不关闭。

5. 实例 notification.onclick = EventListener

onclick 处理程序来监听点击通知的事件 ,比如跳转新的弹窗等

6. 实例 notification.onerror = EventListener

通知显示异常,例如,明明Notification.permissiondefault, 或者denied 调用通知就会显示异常。

7. 实例 notification.onclose = EventListener

通知关闭回调

8. 实例 notification.onshow = EventListener

通知显示回调

9. 其他实例的属性与创建实例传入参数options的属性几乎相同,实际应用可以参考上图表。

示例代码

const notificationFn = (title, body, icon, tag, link) => {
  if (!window.Notification) {
    console.error('当前浏览器不支持Notification!')
    return
  }

  // 展示消息
  const showNotice = () => {
    const notification = new Notification(title, {body, icon, tag})
    notification.onclick = () => {
      window.open(link)
    }
    notification.onerror = e => {
      console.log(e)
    }
  }

  // 获取权限
  if (window.Notification.permission === 'granted') {
    showNotice();
  } else if (window.Notification.permission === 'default') {
    Notification.requestPermission((permission) => {
      if (permission === 'granted') {
        showNotice();
      } else if (permission === 'denied') {
        console.error('已拒绝使用Notification!')
      }
    });
  }
}
const img = 'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9f7641af3056436da04f17b6ce37bb6b~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp'

notificationFn('通知标题', '通知内容', img, Date.now(), 'https://www.juejin.cn')

image.png

参考文档

正春华枝俏,待秋实果茂,与君共勉。

创作不易,动动小手点个👍吧,如有纰漏请再下面评论联系修改。