桌面通知 Notification

为什么需要HTML5的桌面通知

传统的桌面通知可以写一个div放到页面右下角自动弹出来,并通过轮询等等其他方式去获取消息并推送给用户。这种方式有个弊端就是:当我在使用京东 进行购物的时候,我是不知道人人网有消息推送过来给我的,而必须要等我把当前页面切到人人网才知道有消息推送了。这种方式的消息推送它是基于页面存活的, 但是我们需要这么一种策略:无论你在看哪个页面,只要有消息都应该能推送给我看到,这就是webkitNotification要解决的问题。 Notification生成的消息不依附于某个页面,仅仅依附于浏览器。

一个桌面通知生成的正常流程

我们先来看看一个桌面通知是如何生成的:

  • 检查浏览器是否支持Notification
  • 检查浏览器的通知权限(是否允许通知)
  • 若权限不够则获取浏览器的通知权限
  • 创建消息通知
  • 展示消息通知
  • NOTE: 关于第一点的说明需要做一些说明,Notification目前还没有标准化,所以目前只支持chrome19+safari6+;网上有资料显示Firefox26+也支持,但是我拿我的Firefox27检测的结果是无法支持。

notification api基础说明及代码示例

目前notification的实现有两种:一种是之前草案中的形式:webkitNotifications对象, 另一种就是未来标准化的形式:Notification对象。首先来说一下webkitNotifications所包含的内容:

webkitNotifications:

window.webkitNotifications.checkPermission()
//该方法返回0, 1, 2三个值
//0代表PERMISSION_ALLOWED,即允许
//1代表PERMISSION_NOT_ALLOWED,即不允许
//2代表PERMISSION_DENIED,即拒绝

window.webkitNotifications.requestPermission()
//调用该方法将会在浏览器的信息栏弹出一个是否允许桌面通知的提醒,该方法只能由用户主动事件触发,如click 或 mouse over,也就是说你不能在document.ready里面直接调用该方法。

window.webkitNotifications.createNotification('icon-url','title', 'body')
//调用该方法将返回一个实例化的webkitNotifications对象

注意

调用以上方法都会存在安全异常,也就是当前页面的permission是否为0。

实例方法

notificationInstance.show()
//调用该方法将在右下角弹出一个通知窗口
notificationInstance.cancel()
//调用该方法将关闭通知窗口

Notification:

chrome26+ 终端里面输入window.Notification并键入回车键,会发现这东西它也是存在的,根据某些博客的说法,这个Notification会是 webkitNotifications的标准化形态(传说中的进化),这种方式的实现相对于webkitNotifications的实现更简洁,更面 向对象一些。 构造函数:

Notification(title, options)
//@param {String} title 要显示的通知标题
//@param {Object} options 备选项参数,键值对
//option 结构如下
dictionary NotificationOptions {
  NotificationDirection dir = "auto";
  DOMString lang = "";
  DOMString body;
  DOMString tag;
  DOMString icon;//在实例化的时候会异步的去获取
};

//新建一个Notification实例,并根据permission为'granted'来完成notification的显示

var notification = new Notification('Hello Notification',{body:"I'm an enginneer!"});

静态属性:

Notification.Permission:

'default' 等同于拒绝 'denied' 意味着用户不想要通知 'granted' 意味着用户同意启用通知

Test:在chrome的地址栏里面输入http://www.baidu.com, 打开console,并在里面输入Notification.Permission 默认返回的是'default'。

Notes:该属性是只读的不能手动修改

//在百度的首页打开console
Notification.Permission = 'granted'
Notification.Permission   //'default'

实例属性:

以下属性都需要在Notification实例上才能访问,为只读属性,并且就是通过option来赋值

Notification.dir    //
Notification.lang
Notification.Body   //通知的具体内容
Notification.tag    //实例化的notification的id
Notification.icon   //通知的缩略图

静态方法:

Notification.requestPermission() 该方法将会询问用户是否允许显示通知,该方法不能由页面自主调用,必须由用户主动事件触发,还是以百度的页面为例,百度的搜索框的id为'kw':

//不通过事件触发直接调用
Notification.requestPermission()
//页面无反应
 //通过用户主动事件触发来调用
 document.getElementById('kw').onclick=function(){ 
     Notification.requestPermission(); 
 };
//页面信息栏会弹出询问用户是否允许显示桌面通知

注意

当用户同意之后,再次调用该方法则无效,即该方法仅对Notification.Permission不为'granted'的时候起作用

实例方法

Notification.close()    //该方法允许通过代码控制关掉notification

提示

Notification 没有实例方法show(),在Notification实例化的时候,浏览器就已经自动的去处理notification的显示过程了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/jquery/2.1.1/jquery.js"></script>
</head>
<body>

    <button id="button">有人想加你为好友</button>
    <p id="text"></p>
    JS代码:
    <script>

if (window.Notification) {
    var button = document.getElementById('button'),
     text = document.getElementById('text');
    
    var popNotice = function() {
        if (Notification.permission == "granted") {
            var notification = new Notification("Hi,帅哥:", {
                body: '可以加你为好友吗?',
                icon: 'http://image.zhangxinxu.com/image/study/s/s128/mm1.jpg'
            });
            
            notification.onclick = function() {
                text.innerHTML = '张小姐已于' + new Date().toTimeString().split(' ')[0] + '加你为好友!';
                notification.close();    
            };
        }    
    };
    
    button.onclick = function() {
        if (Notification.permission == "granted") {
            popNotice();
        } else if (Notification.permission != "denied") {
            Notification.requestPermission(function (permission) {
              popNotice();
            });
        }
    };
} else {
    alert('浏览器不支持Notification');    
}
     </script>
</body>
</html>