浏览器桌面通知Notification
TIP
浏览器提供的一个桌面通知的接口,它是浏览器原生的API,挂载在window对象上,该api的调用需要用户授权
获取授权
在调用 Notification 相关API之前,需要先使用Notification对象上的静态方法Notification.requestPermission()来获取授权
// 申请桌面通知权限
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时相同
使用
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
- 关闭通知时触发
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
- 关闭一个以前显示的通知
let notice = new Notification('title')
notice.close()
函数封装
/*
* @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()
}
调用
import createNotify from '@/hooks/userBrowserNotify'
createNotify({
title: $t('system.systemNotice'),
options: {
badge: systemStore.logo,
body: msg
},
duration: 5000
})