Skip to content
On this page

浏览器桌面通知Notification

TIP

浏览器提供的一个桌面通知的接口,它是浏览器原生的API,挂载在window对象上,该api的调用需要用户授权

获取授权

在调用 Notification 相关API之前,需要先使用Notification对象上的静态方法Notification.requestPermission()来获取授权

javascript
// 申请桌面通知权限
function requestNotificationPermission() {
  // 系统不支持桌面通知
  if (!window.Notification) {
    return Promise.reject('系统不支持桌面通知')
  }
  return Notification.requestPermission().then(function (permission) {
    if (permission === 'granted') {
      return Promise.resolve()
    }
    return Promise.reject('用户已禁止桌面通知权限')
  })
}

授权状态

调用Notification.requestPermission()获取的permissionResult可能的值为

  • denied:用户拒绝了通知的显示
  • granted:用户允许了通知的显示
  • default:因为不知道用户的选择,所以浏览器的行为与denied时相同

使用

javascript
let notification = new Notification(title, options)

title - 设置显示通知的标题 (必填, 否则会报错!)

options - 可选参数

· dir :文字的方向(auto 自动、ltr 从左至右、rtl 从右至左);

· lang :指定通知所用的语言;

· body:通知额外显示的字符串,也就是正文部分,会在标题下方显示;

image: 预览的大图;

· tag:赋予通知一个ID(唯一的),用于对通知进行刷新、替换或移除(这块对于多个通知有用),默认为空,当tag相同时,重复构造实例。新通知会替换就通知,反之,通知不会替换,而是像盖楼层一样叠加;

· icon:一个图片的URL,用于显示通知图标;

· requireInteraction : true // 是否一直保持有效(是否一直保持通知的显示,默认为false,会自动关闭),设置为true时,必须由用户手动关闭或者 调用实例的 notification.close() 方法进行关闭。

· data : 这是一个自定义的属性,里边可以定义一些自己属性

事件处理函数

(1)notice.onclick - 每当用户点击通知是触发

注意:该方法的默认行为是将 焦点移到与该通知相关联的 browsing context 的窗口. 如果你不希望这样, 可以在 event 对象上调用 preventDefault().

(2)notice.onshow - 当通知显示时触发( 过时API )

(3)notice.onerror - 当通知遇到错误时触发( 过时API )

(4)notice.onclose - 关闭通知时触发

javascript
let notice = new Notification("title")
notice .onclick = function(e) {
  let e = e || window.event
  e.preventDefault(); // 阻止默认事件
  window.open('http://www.baidu.com', '_blank') // 打开一个新页面
}

实例方法

notice.close - 关闭一个以前显示的通知

javascript
let notice = new Notification('title')
notice.close()

函数封装

javascript
/*
 * @param {string} title - 消息标题
 * @param {object} options - 消息配置
 * @param {number} duration - 消息时长
 * @param {function} onclick
 * @param {function} onshow
 * @param {function} onclose
 * @param {function} onerror
 * @return {object}
 */
export default async function createNotify(data) {
  // 一些判断
  if (window.Notification) {
    if (Notification.permission === 'granted') {
      return notify(data)
    } else if (Notification.permission === 'default') {
      let [err, status] = await Notification.requestPermission()
        .then((status) => [null, status])
        .catch((err) => [err, null])
      return err || status === 'denied' ? Promise.reject() : notify(data)
    }
  }
  // 构造实例
  function notify(data) {
    let { title, options, duration } = data
    options.requireInteraction = true
    let notification = new Notification(title, options)
    setTimeout(() => notification.close(), duration || 5000)
    // 绑定事件
    let methods = ['onclick', 'onshow', 'onclose', 'onerror']
    for (let i = 0; i < methods.length; i++) {
      let method = methods[i]
      if (typeof options[method] === 'function') {
        notification[method] = options[method]
      }
    }
    return notification
  }
  return Promise.reject()
}

调用

javascript
import createNotify from '@/hooks/userBrowserNotify'

createNotify({
  title: $t('system.systemNotice'),
  options: {
    badge: systemStore.logo,
    body: msg
  },
  duration: 5000
})