很久以前,做了个小需求,关于浏览器通知。用户在点击提交订单之后 后台管理系统需要在浏览器端显示用户订单通知消息,于是整理了部分关于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)
效果
然而这种提示有致命的缺陷,就是需要用户一直打开浏览器,并且时刻关注title部分是否有变化,于是HTML Notification就诞生了
HTML5 Web Notification
Notifications API 允许网页或应用程序在系统级别发送在页面外部显示的通知;这样即使应用程序空闲或在后台,Web 应用程序也会向用户发送信息。
总体兼容性
各API兼容性
点击展开查看兼容性
看到这么密密麻麻的兼容性,很容易让人望而却步,所以这里笔者整理出一份常用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端不考虑) |
| renotify | renotify 是 Notification 接口的只读属性,如果有新的通知替换了一个旧的通知,这个属性指明用户是否应该重新收到通知。默认为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.permission是default, 或者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')
参考文档
正春华枝俏,待秋实果茂,与君共勉。
创作不易,动动小手点个👍吧,如有纰漏请再下面评论联系修改。