起因:在做一些交互式页面时,如果切换到浏览器其他页面,或者是缩小了浏览器等等,都可能导致忽略了该关注的页面有新的消息或回调,所以需要有比较友好的提醒方式(例如有个消息弹窗提示)。
解决:Notification 一个H5的新特性,可以实现Web的桌面通知功能。它生成的消息通知不需要依附某个页面,而是依附于浏览器,从而可以让我们不需要停留在页面上。
使用桌面通知流程:
1、检查浏览器是否支持Notification;
2、检查浏览器的通知权限;
3、若没有权限,先获取浏览器的通知权限;
4、创建消息通知;
5、展示消息通知;
6、设置关闭回调;
示例场景:聊天会话;
预计效果:每次新消息都弹窗提醒,且点击弹窗可打开对应会话,关闭该会话所有消息通知,保留其他会话消息通知;
小坑:Windows上谷歌浏览器每次只展示一个弹窗,360、搜狗每次最多展示3个;Mac上谷歌跟360都可展示所有弹窗,无搜狗浏览器可安装,不知道效果;
使用示例:
// 消息通知提示音
const notificationAudio = new Audio('https://img-fe.tengzhihh.com/audio/c58fb135c2546f.mp3');
// 消息弹窗数组
const notificationInstanceArr: Array<{ [propName: string]: number | Notification }> = [];
Function handleNotification () {
// 检查是否支持
if (!('Notification' in window)) {
console.log('浏览器不支持消息通知');
return;
}
// 创建配置项
const options = {
body: '您有新的未读消息', // 展示内容
silent: false, // 是否静音
lang: 'ZH',
sticky: true, // 是否粘性展示,不轻易被清理
// renotify: true, // 弹窗内容更新,是否重新通知,需与tag搭配使用
requireInteraction: true, // 是否保持,不自动关闭
};
// 检查权限是否已获取 已获取为granted
if (Notification.permission !== 'granted') {
// 未允许权限,则申请权限
Notification.requestPermission(function (status) {
if (status == 'granted') {
// 创建提醒
const notification = new Notification('新消息提醒', options);
// 设置点击事件
notification.onclick = function () {
handleMessageFocus(data);
};
// 存储通知实例,保留最新三个
if (notificationInstanceArr.length == 3) {
const instance = notificationInstanceArr.shift()?.instance;
instance?.close();
}
notificationInstanceArr.push({
id: target.id,
instance: notification,
});
// 播放通知音频
notificationAudio?.play();
}
});
} else {
// 已有权限,重复操作即可
const notification = new Notification('新消息提醒', options);
notification.onclick = function () {
handleMessageFocus(data);
};
if (notificationInstanceArr.length == 3) {
const instance = notificationInstanceArr.shift()?.instance;
instance?.close();
}
notificationInstanceArr.push({
id: target.id,
instance: notification,
});
notificationAudio?.play();
}
}
function handleMessageFocus (target) {
// 可以在这里 根据新消息target,处理展示具体会话逻辑
// ...
// 展示原有页面
window.focus();
// 删除点击的会话通知
for (let i = 0; i < notificationInstanceArr.length; i++) {
if (notificationInstanceArr[i].id == target.id) {
notificationInstanceArr[i].instance.close();
notificationInstanceArr.splice(i, 1);
i--;
}
}
}
注意:系统设置、浏览器设置相关的权限都能导致通知无效,无效时可以优先看看权限设置。