Sivo 悉见

使用HTML5 Notification API开启浏览器桌面提醒

匿名 · 更新于 2015/11/16

前两天发现一款app,安装了app和相应的chrome插件以后,可以将安卓手机上的消息在电脑桌面上弹窗显示。这样一来,工作的时候就可以完全把手机扔在一边安心工作了,而不用时时查看是否错过了什么消息,如下图所示:

notificationnotification

这个应用实现的原理其实很简单,大概原理是,监听手机的消息系统,当有新消息的时候就同步到服务器,服务器接收到通知,然后通过HTML5的Notification API推送消息到电脑。之前有玩过这个API,这次再完整地学习一遍,记录下来。

如何使用

申请权限

出于安全考虑,要发送桌面消息,需要先申请用户授权。Notification对象提供了一个静态的方法——requestPermission(),它接收一个回调函数作为参数,并把返回值传递给回调函数作为参数:

Notification.requestPermission(function(status){
            if(Notification.permission !== status){
                Notification.permission = status;
            }
        });

返回值为字符串,有以下三个值:

  • default
  • granted
  • denied

默认为default,也就是需要询问,表现和denied一样。

创建消息

用户授权以后,你就可以通过下面方式创建一条桌面提醒了:

var n = new Notification(title, options);    

options为字典,传入Notification对象的属性。

属性

Notification对象有如下几个只读属性:

  • dir(文字方向,经测试都不支持)
  • lang(语言)
  • body(消息体)
  • tag(标签)
  • icon(icon地址)

这几个属性都可以在创建消息的时候,作为option传入Notification构造函数。提一下tag属性,在有很多消息的时候,这个属性就非常有用,它会用拥有相同tag的最新的消息取代之前的消息,只显示一条最新的消息。比如在一个聊天室系统中,同时和几个人在聊天的时候,就可以以人名为tag显示不同人的最新消息。

事件

Notification对象有四个事件,分别是

  • onshow()
  • onclick()
  • onclose()
  • onerror()

分别在消息显示、被点击、被关闭和出错的时候被触发。下面的例子中完整的展示了这四个事件的使用。通常情况下,只需要处理点击事件就够了,比如点击消息后跳转到某一特定的页面。

例子

下面这个例子当你首次授权的时候,点击按钮会得到三条消息,但通过tag让它只显示最新的一条消息。以后每次点击按钮的时候都会得到一条加了时间戳的消息,点击消息体或关闭消息都会触发相应的事件。

Notify me!
window.addEventListener("load", function(){
    if(Notification && Notification.permission !== "granted"){
        Notification.requestPermission(function(status){
            if(Notification.permission !== status){
                Notification.permission = status;
            }
        });
    }
    var button = document.getElementsByTagName("button")[0];
    button.addEventListener("click", function(){
        var t = new Date().toLocaleString();
        var options={
            dir: "ltr",
            lang: "utf-8",
            icon: "http://ihuster.com/static/avatar/m_default.png",
            body: "你好呀,欢迎留言交流呀"
        };
        if(Notification && Notification.permission === "granted"){
            var n = new Notification("HUSTecho: "+ t, options);    
            n.onshow = function(){
                console.log("You got me!");
            };
            n.onclick = function() {
                alert("You clicked me!");
                window.location = "/";
            };
            n.onclose = function(){
                console.log("notification closed!");
            };        
            n.onerror = function() {
                console.log("An error accured");
            }            
        }else if(Notification && Notification.permission !== "denied") {
            Notification.requestPermission(function(status){
                if(Notification.permission !== status){
                    Notification.permission = status;
                }

                if(status === "granted"){
                    for(var i = 0; i < 3; i++){
                        var n = new Notification("Hi! " + i, {
                            tag: "Beyoung",
                            icon: "http://ihuster.com/static/avatar/b_default.png",
                            body: "你好呀,我是第" + i +"条消息啦!"
                        });
                    }
                }
            });
        }else{
            alert("Hi!");
        }
    });
});

浏览器兼容

桌面版chrome实现的最为完善,相当于一个附属app了,chrome把消息系统独立了出来,点击桌面工具栏的提醒图标可以打开消息中心查看所有的消息,一次最多可以显示三条消息,firefox一次只能显示一条消息,循环发出多条消息的话firefox居然一条也不显示。。。手机上目前只有firefox支持,其他的浏览器都不支持,安卓上的chrome提醒应该在开发中(PS:没测过safari,其他的浏览器都是使用的最新版的)。

can i usecan i use
chrome message boxchrome message box
firefox mobile notificationfirefox mobile notification

下一步计划

准备使用socket.js + nodejs做一个聊天室。使用用户名作为tag以显示单一聊天对象的最新消息,点击后跳转到与该聊天对象聊天的界面。但考虑到浏览器的性能问题,实测chrome最新版连续显示20条左右的信息,再点击通知栏的消息图标就会卡住,当然也有可能是我的电脑不行了吧。。所以使用pageVisibility API来优化性能,当聊天对象正在聊天页面的时候就不显示消息,否则才显示。



转自:http://xuhong.github.io/2014/05/22/notification/