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

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

https://developer.mozilla.org/zh-CN/docs/Web/API/Notification

前两天发现一款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来优化性能,当聊天对象正在聊天页面的时候就不显示消息,否则才显示。

参考资料:

Notifications API 的通知接口用于向用户配置和显示桌面通知。

Note: 此特性在 Web Worker 中可用。

构造方法Edit

let notification = new Notification(title, options)

参数

title一定会被显示的通知标题options 可选一个被允许用来设置通知的对象。它包含以下属性:

  • dir : 文字的方向;它的值可以是 auto(自动), ltr(从左到右), or rtl(从右到左)
  • lang: 指定通知中所使用的语言。这个字符串必须在 BCP 47 language tag 文档中是有效的。
  • body: 通知中额外显示的字符串
  • tag: 赋予通知一个ID,以便在必要的时候对通知进行刷新、替换或移除。
  • icon: 一个图片的URL,将被用于显示通知的图标。

属性Edit

静态属性

这些属性仅在 Notification 对象上有效。

Notification.permission 只读一个用于表明当前通知显示授权状态的字符串。可能的值包括:denied (用户拒绝了通知的显示), granted (用户允许了通知的显示), or default (因为不知道用户的选择,所以浏览器的行为与 denied 时相同).

实例属性

这些属性仅在 Notification 的实例中有效。

Notification.title 只读 (moz only)在构造方法中指定的 title 参数。Notification.dir 只读通知的文本显示方向。在构造方法的 options 中指定。Notification.lang 只读通知的语言。在构造方法的 options 中指定。Notification.body 只读通知的文本内容。在构造方法的 options 中指定。Notification.tag 只读通知的 ID。在构造方法的 options 中指定。Notification.icon 只读通知的图标图片的 URL 地址。在构造方法的 options 中指定。

事件处理

Notification.onclick处理 click 事件的处理。每当用户点击通知时被触发。Notification.onshow处理 show 事件的处理。当通知显示的时候被触发。Notification.onerror处理 error 事件的处理。每当通知遇到错误时被触发。Notification.onclose处理 close 事件的处理。当用户关闭通知时被触发。

方法Edit

静态方法

这些方法仅在 Notification 对象中有效。

Notification.requestPermission()用于当前页面想用户申请显示通知的权限。这个方法只能被用户行为调用(比如:onclick 事件),并且不能被其他的方式调用。

实例方法

这些方法仅在 Notification 实例或其 prototype 中有效。

Notification.close()用于关闭通知。

Notification 对象继承自 EventTarget 接口。

EventTarget.addEventListener()Register an event handler of a specific event type on the EventTarget.EventTarget.removeEventListener()Removes an event listener from the EventTarget.EventTarget.dispatchEvent()Dispatch an event to this EventTarget.

Additional methods for Mozilla chrome code

Mozilla extensions for use by JS-implemented event targets to implement on* properties. See also WebIDL bindings.

  • void setEventHandler(DOMString type, EventHandler handler) 
  • EventHandler getEventHandler(DOMString type) 

ExampleEdit

假定有如下 HTML:

<button onclick="notifyMe()">Notify me!</button>

接下来发送一条通知:

function notifyMe() { // Let's check if the browser supports notifications if (!("Notification" in window)) { alert("This browser does not support desktop notification"); } // Let's check if the user is okay to get some notification else if (Notification.permission === "granted") { // If it's okay let's create a notification var notification = new Notification("Hi there!"); } // Otherwise, we need to ask the user for permission else if (Notification.permission !== 'denied') { Notification.requestPermission(function (permission) { // If the user is okay, let's create a notification if (permission === "granted") { var notification = new Notification("Hi there!"); } }); } // At last, if the user already denied any notification, and you  // want to be respectful there is no need to bother them any more. }

See the live result

在 codepen 中打开在 jsfiddle 中打开

规范Edit

规范 状态 备注
Notifications API Living Standard Initial specification.

权限Edit

当你要在开放 web 应用中使用通知是,请确保将 desktop-notification 权限添加到你的 manifest 文件中。通知可以被用于任何权限级别,hosted 或更高。

"permissions": { "desktop-notification":{} }

浏览器兼容性Edit

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support webkit (see notes)
22
4.0 moz (see notes)
22
未实现 25 6 (see notes)

Gecko 备忘

  • 在 Firefox 22 (Firefox OS <1.2) 之前,创建一个新的通知必须使用 navigator.mozNotification 对象的 createNotification 方法。
  • 在 Firefox 22 (Firefox OS <1.2) 之前,当调用 show 方法时通知才会被显示出来,并且只支持 click 和 close 事件。
  • Nick Desaulniers 编写了一个 Notification shim 以向前和向后兼容各种版本的实现。
  • 在 Firefox OS 有个特别的问题, 你可以传递一个图标路径 用于通知,但是如果应用被打包了你就不能使用相对路径,比如: /my_icon.png。同样的,你也不能这样用: window.location.origin + "/my_icon.png",因为 window.location.origin 的值在打包的应用里为 null。 清单来源字段 可以修复这个问题,但是这个方法只在 Firefox OS 1.1+ 版本中有效。不过有个潜在的解决方案可以用于 Firefox OS <1.1 版本,就是 传递图标的位于外部服务器的绝对 URL 。这个方案并不理想,如通知要立即显示而没有图标,那么将会请求服务器,但是可以用于所有版本的 Firefox OS。

Chrome 备忘

Safari 备忘

  • Safari 在 Safari 6 版本开始支持通知,但是只能在 Mac OSX 10.8+ (Mountain Lion) 中使用。

请参见Edit

    A+
发布日期:2017年08月16日  所属分类:未分类

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: