需求需要实现当浏览器最小化时,如果有新通知,实现浏览器闪烁,或者实在不行在浏览器标题栏闪烁(这个似乎相当于没有通知。。)。基于技术研究的目的,在网络上查找有没有相关实现方式,发现,大多不是真正的实现任务栏闪烁,似乎纯js无法实现,还需要win32底层API的支持。。。无奈转而研究能不能折中通过弹框的方式通知。发现可以通过HTML的Notification API实现,下面先介绍简单的浏览器标题栏闪烁的方式,毕竟也有一些应用场景。
一、浏览器标题栏闪烁
实际上就是基于document的title属性,在接收到新消息时,判断焦点是否在当前页面来决定是否闪烁浏览器页面通知栏的,如果这时浏览器最小化当然也就看不到这个闪烁通知了。
下面模拟这个场景,定义一个变量存储是否获取焦点,然后通过定时器,循环判断这个变量,如果获取焦点就不设置标题,如果没获取到焦点就循环修改title值达到闪烁的目的:
<html>
<head>
<title>地址栏闪烁</title>
<script type="text/javascript">
var isShine = true;
//Chrome/FireFox
window.onfocus = function() {
isShine = false;
};
window.onblur = function() {
isShine = true;
};
//IE
document.onfocusin = function() {
isShine = false;
};
document.onfocusout = function() {
isShine = true;
};
debugger;
//保存原始title,便于还原
var defaultTitle = document.title
setInterval(function() {
var title = document.title;
//判断是否获取焦点
if (isShine == true) {
//如果没有获取焦点就判断名称是否包含未读消息
if (/未读消息/.test(title) == false) {
//如果包含就显示为空
document.title = '【未读消息】';
} else {
//否则显示未读消息,间隔0.5秒实现闪烁
document.title = '【 】';
}
} else {
//如果获取到焦点就不闪烁,使用元素标题
document.title = defaultTitle;
}
}, 500);
</script>
</head>
<body>
测试浏览器标题栏闪烁
</body>
</html>
二、使用HTML5 Web Notification桌面通知
对于B/S程序另一种折中且不错的通知方式是使用HTML5 Notification API实现桌面弹窗的通知。语法可以参考https://developer.mozilla.org/en-US/docs/Web/API/notification
1、实例化Notification对象
构造函数结构如下:
function spawnNotification(theBody,theIcon,theTitle) {
var options = {
body: theBody,
icon: theIcon
}
var n = new Notification(theTitle,options);
}
其中参数theBody是消息通知的正文,theTitle是消息通知的标题,theIcon是显示的图标。
Notification 对象有许多静态属性,比较常用的比如Notification.permission是只读属性,有三个值:
- denied — 用户拒绝显示通知;
- granted — 用户允许显示通知;
- default — 用户不知情,所以认为是拒绝。
2、Notification属性值
实例化Notification 对象时还有许多只读参数,上面列出的theTitle是必选参数,options对象里面的是可选参数,可以针对不同场景使用,比如:
body—示在标题下面的正文内容;
icon—字符串类型,通知弹框左侧显示的图标地址;
dir—默认值是auto, 可以是ltr或rtl,通知正文的水平书写顺序;
renotify—布尔值。新通知出现的时候是否替换之前的。默认false,表示从下到上层叠显示,如果设为true,则表示替换,当前的通知只会出现一个。设为true时,必须同时设置tag属性值。
silent—布尔值,通知出现的时候,是否要有声音,默认false, 表示无声。
sound—字符串,音频地址,表示通知出现要播放的声音。
3、Notification实例方法
Notification包含一些事件处理方法,例如:
当用户每次触发点击事件时执行,格式:
Notification.onclick = function(event) { ... };
当用户点击通知时打开新页面:
notification.onclick = function(event) {
event.preventDefault(); // prevent the browser from focusing the Notification's tab
window.open('http://www.mozilla.org', '_blank');
}
2)Notification.onclose
当用户关闭通知时触发事件,如果不手动关闭通知,过一段时间也会自动关闭。
Notification.onclose = function() { ... };
3)Notification.onerror
通知显示异常时触发,比如当无权显示通知时显示通知。
Notification.onerror = EventListener;
4、实例代码
function showNotification(){
//判断浏览器是否支持Notification对象
debugger;
var isFocus = true;
//Chrome/FireFox
window.onfocus = function() {
isFocus = true;
};
window.onblur = function() {
isFocus = false;
};
//IE
document.onfocusin = function() {
isFocus = true;
};
document.onfocusout = function() {
isFocus = false;
};
if(window.Notification){
$("#btn").on('click',function(){
if(!isFocus){
//判断是否有权限显示通知
if(Notification.permission=="granted"){
pushNotice();
}else if(Notification.permission!="denied"){
//如果不是拒绝显示通知就请求允许显示通知
Notification.requestPermission(function(permission){
pushNotice();
});
}
}
});
}else{
$.alert({
title: '信息',
content: '浏览器不支持桌面通知'
});
}
}
function pushNotice(){
//判断是否有显示通知的权限
if(Notification.permission=="granted"){
//初始化通知对象
var options = {
body: "您有新的未读消息"
}
var notice = new Notification("通知",options);
}
}
测试通过判断窗口是否失去焦点来决定是否显示通知,发现在页面存在一些操作的情况下,导致错误触发foucus和blur方法,因此决定换一种方式,后来发现有一个document.hidden属性表示页面是(true)否(false)隐藏。因此改为通过判断这个属性来判断窗口是否隐藏决定是否显示通知。
本地测试成功后在测试服务器上测试,由于使用的是Chrome浏览器,而部署的应用是http的,Chrome从v68开始要求网站使用https协议,如果不是的话会显示不安全,导致Notification无法使用。。。因此如果是使用的Chrome浏览器,想要使用Notification API,必须将应用升级成https。。。