前言

前段时间接到一个需求,我们的web系统有电话接听功能。产品希望有电话呼入的时候,能够有效提示用户,无论用户是否在当前的系统页签上,甚至浏览器被最小化以后也能提醒用户。就着这个需求,我做了一些探索。

前端对用户的通知一般局限于页面之内,比如alert,confirm。或者js控制一个弹窗提醒用户。有些场景需要在页面之外通知用户,即当用户页签不在本页面,或者浏览器已经被收起来的情况。

本文介绍一些浏览器通知方式。

方法一:闪烁浏览器标题

利用document.title修改页签的标题,使用定时器来回切换内容实现标题闪烁,引起用户注意。

例子:

function sendNotificationFn(message, time) {
var oldTitle = document.title; // 保存原有标题
var changeVal = 1;
var notice = setInterval(function() {
if (changeVal) {
document.title = message;
changeVal = 0
} else {
document.title = oldTitle;
changeVal = 1
}
}, time || 1000);

return notice;
}

sendNotificationFn('有新的通知', 500);
// 中止通知
clearInterval(notice);

使用上述方法就可以不断闪烁title,引起用户的注意。方法会返回定时器,清除定时器重新设置title就可以恢复正常。

效果如图

浅谈浏览器通知 Notification_chrome浏览器

修改title是兼容性比较好,实现比较简单的一种方式,但是用最小化浏览器效果就很不好了,为了解决这个问题。html5推出notification api

方法二:web notification

我们先来看一下效果

浅谈浏览器通知 Notification_字符串_02

会在系统的右下方显示一个通知,即便页签不在用户的视窗内,也可以触发该效果。

一个简单的例子

function sendNotification() {
new Notification("通知标题:", {
body: '通知内容',
icon: 'https://pic1.zhuanstatic.com/zhuanzh/50b6ffe4-c7e3-4317-bc59-b2ec4931f325.png'
})
}
if (window.Notification.permission == "granted") { // 判断是否有权限
sendNotification();
} else if (window.Notification.permission != "denied") {
window.Notification.requestPermission(function (permission) { // 没有权限发起请求
sendNotification();
});
}
如果没有弹出弹窗,有两种可能

  1. 浏览器不支持Notification API
  2. 需要获得通知授权。

是否支持Notification可以通过window.Notification是否存在来判断,如果支持的情况下没有弹出就需要获得授权。通过调用Notification.requestPermission(callback)来获取用户授权,授权后可正常弹出。

浅谈浏览器通知 Notification_ico_03

也可以点击图中的小锁图标,允许通知。

不同浏览器的实现样式略有不同,js代码不能控制具体的位置和样式,可以确定标题,内容,和一个系统icon。对于chrome浏览器,一般几秒钟后会被自动关闭,其他浏览的各个版本实现各有不同,如我用的360极速, 长时间也不会关闭, 可以看到已经显示了12分钟。

浅谈浏览器通知 Notification_chrome浏览器_04

chrome浏览器效果实现

浅谈浏览器通知 Notification_chrome浏览器_05

可以通过调用Notification.close()方法,主动关闭关闭通知。

new Notification(title, options) 通过new构造,调用通知方法。其中title是必填参数,表示通知的标题内容,options是可选参数,详见下表:


属性

含义

类型

body

内容主体

字符串

icon

通知图标

字符串

silent

是否需要声音

布尔值

sound

声音地址,可以播放提示声音

字符串

data

任意类型和通知相关联的数据

对象

vibrate

震动模式

数组

tag

通知标识

字符串

renotify

通知是否使用叠加效果,默认true,fasle则为替换

布尔值

noscreen

是否不在屏幕上显示通知,用于移动端,默认false

布尔值

通知堆叠效果 false仅显示最新的一个

浅谈浏览器通知 Notification_字符串_06

其中vibrate是个很有意思的属性,在Notification使用vibrate属性可以使设备震动,填入[300, 100, 300], 表示设备振动 300毫秒,然后停止100毫秒,再振动300毫秒

new Notification("通知标题:", {
body: '通知内容',
vibrate: [300, 100, 300],
icon: 'https://pic1.zhuanstatic.com/zhuanzh/50b6ffe4-c7e3-4317-bc59-b2ec4931f325.png'
})

使用该效果虽然更能引起用户的注意,但是也会有过分打扰用户。有些浏览器也没有实现该效果,慎重使用。

再来看看Notification的相关事件


事件名

含义

Notification.onclick

通知被点击时

Notification.onerror

通知显示异常时,躲在用户没有给通知时触发

Notification.onclose

通知被关闭时

Notification.onshow

通知显示时

Notification还提供了一些只读属性,可供一些特殊需求使用,大部分和options相同 列如:title,body,tag,icon,silent,timestamp(通知创建的时间),noscreen等

Notification的兼容性

浅谈浏览器通知 Notification_字符串_07

在现代浏览器的支持还是比较好的,edge的高版本也做了支持,不过对于IE已经其他老版本的浏览器,还是需要考虑 兼容性和备用方案。

iNotify.js 方法库介绍

上述两种方法使用的时候免不了要自己封装,尤其是Notification,api和属性都比较多,推荐使用iNotify.js来解决通知问题 iNotify.js。可以帮助实现浏览器的 title 闪烁、滚动、声音提示、chrome、Firefox、Safari等系统通知。

这个例子是进行声音提示

var iNotify = new iNotify().init();
//推荐下面写法
var iNotify = new iNotify({
message: '有消息了。',//标题
effect: 'flash', // flash | scroll 闪烁还是滚动
openurl:"http://www.bing.com", // 点击弹窗打开连接地址
onclick:function(){ //点击弹出的窗之行事件
console.log("---")
},
//可选播放声音
audio:{
//可以使用数组传多种格式的声音文件
file: ['msg.mp4','msg.mp3','msg.wav']
//下面也是可以的哦
//file: 'msg.mp4'
},
//标题闪烁,或者滚动速度
interval: 1000,
//可选,默认绿底白字的 Favicon
updateFavicon:{
// favicon 字体颜色
textColor: "#fff",
//背景颜色,设置背景颜色透明,将值设置为“transparent”
backgroundColor: "#2F9A00"
},
//可选chrome浏览器通知,默认不填写就是下面的内容
notification:{
title:"通知!",//设置标题
icon:"",//设置图标 icon 默认为 Favicon
body:'您来了一条新消息'//设置消息内容
}
})
import Notify from '@wcjiang/notify';

const notify = new Notify({
effect: 'flash',
interval: 500,
});
notify.setFavicon('1');
notify.setTitle('New title');
notify.setInterval(200);
notify.notify({ openurl: 'http://localhost:8084/#/admin/home' });

setTitle 用来设置标题

setInterval 用来配置闪动间隔

setFavicon 用来配置角标数字, 如下图

浅谈浏览器通知 Notification_字符串_08

notify.notify() 直接发起提示

具体使用可以参看 https://github.com/cywcd/iNotify, 非常详细。

总结

H5的Notification为浏览器通知提供了一个很好的解决方案,用户体验优秀,结合自定义声音,能带来不错的体验,但是目前的兼容性一般,即便是使用iNotify.js,所以在生产环境中使用需要注意使用场景。在移动端的实现会更不稳定一些,建议多多测试,做好保底方案。

文末福利

本文并留下评论,我们将抽取第 10 名留言者(依据公众号后台排序),转转纪念 T 恤一件,大家快转发起来吧~

浅谈浏览器通知 Notification_字符串_09

浅谈浏览器通知 Notification_chrome浏览器_10