HTML5新特性之Web Notifications

时间:2022-11-24 19:34:05

原文地址:http://blog.csdn.net/liuhe688/article/details/41971215

今天我们先来讲解一下桌面通知,即Web Notifications技术。

Web Notifications是HTML5中一个令人欣喜的新特性,它支持开发者配置和显示桌面通知,为用户提供更好的体验,最令人称赞的是,即使用户忙于其他工作时也可以收到来自页面的消息通知,例如一个新邮件的提醒,或者一个在线聊天室收到的消息提醒等等。

接下来,我们就试着一步一步创建我们自己的消息通知。

要创建消息通知,首先我们要创建一个消息框,这非常很简单,直接使用window对象下面的Notification类即可,代码如下:

[javascript] view plain copy
  1. var n = new Notification("sir, you got a message", {  
  2.     icon: 'img/icon.png',  
  3.     body: 'you will have a meeting 5 minutes later.'  
  4. });  

在Notification这个类的构造函数中,有两个重要的参数,第一个是消息的标题,第二个是消息体对象,其中包括消息框的图标(icon)和消息内容(body)。

在执行完以上代码后,我们就成功地创建了一个消息框实例,在Chrome下面它最终会显示成这样:

HTML5新特性之Web Notifications

到这里我们已经成功了一半,但能不能正确地显示出这个消息框,最终还取决于用户的授权。鉴于浏览器的安全机制,只有用户同意网页弹出消息通知框,消息通知才能够真正的显示出来。所以现在我们要做的就是申请用户授权。

Notification类提供了一个requestPermission方法,用来请求用户授权,代码如下:

[javascript] view plain copy
  1. Notification.requestPermission(function(status) {  
  2.     //status是授权状态,如果用户允许显示桌面通知,则status为'granted'  
  3.     console.log('status: ' + status);  
  4.   
  5.     //permission只读属性  
  6.     var permission = Notification.permission;  
  7.     //default 用户没有接收或拒绝授权请求 不能显示通知  
  8.     //granted 用户接受授权请求 允许显示通知  
  9.     //denied  用户拒绝授权请求 不允许显示通知  
  10.   
  11.     console.log('permission: ' + permission);  
  12. });  

当这段代码执行时,浏览器会询问用户,是否允许该站点显示消息通知,如下图所示:

HTML5新特性之Web Notifications

如果用户点击了左边的Block按钮,无论我们如何创建Notification实例,消息始终是无法显示出来的;只有用户选择了Allow按钮,代码才能正确执行并且显示出消息框来。

正如上面代码中所描述的那样,requestPermission函数执行完后,会进入一个回调函数,该回调函数可以传递一个status参数,表示在用户做出选择后,最终的授权状态。如果用户点击了授权提示右边的关闭按钮,相当于忽视了授权请求,此时status为default,在default状态下是无法显示消息的;如果用户点击了Block按钮拒绝授权请求,则status会是denied状态,自然是无法显示消息;如果用户点击了Allow按钮接受授权请求,则此时status会变成granted状态,只有在granted状态下才可以正确显示消息。

同时,在执行完授权请求后,浏览器会将权限状态赋到Notification的permission属性上面,该属性对于开发者来讲是只读的,它的值跟上述的status值是一样的。所以如果我们要显示一个消息通知,可以先判断一下是否拥有权限:

[javascript] view plain copy
  1. if (Notification.permission === 'granted') {  
  2.     //show notification  
  3. }  

正如上面描述的那样,当权限为granted时,我们就可以显示消息通知了。但是单纯的显示一个消息框是没有任何吸引力的,所以消息通知应该具有一定的交互性,在显示消息的前前后后都应该有事件的参与。Notification一开始就制定好了一系列事件函数,开发者可以很方面的使用这些函数处理用户交互:

[javascript] view plain copy
  1. var n = new Notification("sir, you got a message", {  
  2.     icon: 'img/icon.png',  
  3.     body: 'you will have a meeting 5 minutes later.'  
  4. });  
  5.   
  6. //onshow函数在消息框显示时会被调用  
  7. //可以做一些数据记录及定时操作等  
  8. n.onshow = function() {  
  9.     console.log('notification shows up');  
  10.     //5秒后关闭消息框  
  11.     setTimeout(function() {  
  12.         n.close();  
  13.     }, 5000);  
  14. };  
  15.   
  16. //消息框被点击时被调用  
  17. //可以打开相关的视图,同时关闭该消息框等操作  
  18. n.onclick = function() {  
  19.     alert('open the associated view');  
  20.     //opening the view...  
  21.     n.close();  
  22. };  
  23.   
  24. //当有错误发生时会onerror函数会被调用  
  25. //如果没有granted授权,创建Notification对象实例时,也会执行onerror函数  
  26. n.onerror = function() {  
  27.     console.log('notification encounters an error');  
  28.     //do something useful  
  29. };  
  30.   
  31. //一个消息框关闭时onclose函数会被调用  
  32. n.onclose = function() {  
  33.     console.log('notification is closed');  
  34.     //do something useful  
  35. };  
我们可以看到,Notification有4个常用的函数可以用来处理事件交互,onshow函数可以在消息展示时执行,onclick函数可以在用户点击消息后被调用,onclose函数是在消息框被关闭时被调用,onerror函数是发生错误时被调用,上面也提到了,如果没有被授权而继续创建消息通知,也会执行onerror函数。掌握了这几个函数的应用,基本上可以很好地处理消息事件了。

最后,我们会把这些步骤组织起来,形成一个简单的示例,来更好地展示这个新特性。

首先,创建下面这个文件结构:

HTML5新特性之Web Notifications

然后我们要把上面讲的几个步骤的代码组织起来,形成一个JavaScript对象,如下面代码所示:

[javascript] view plain copy
  1. var NotificationHandler = {  
  2.     isNotificationSupported: 'Notification' in window,  
  3.     isPermissionGranted: function() {  
  4.         return Notification.permission === 'granted';  
  5.     },  
  6.     requestPermission: function() {  
  7.         if (!this.isNotificationSupported) {  
  8.             console.log('the current browser does not support Notification API');  
  9.             return;  
  10.         }  
  11.   
  12.         Notification.requestPermission(function(status) {  
  13.             //status是授权状态,如果用户允许显示桌面通知,则status为'granted'  
  14.             console.log('status: ' + status);  
  15.   
  16.             //permission只读属性  
  17.             var permission = Notification.permission;  
  18.             //default 用户没有接收或拒绝授权 不能显示通知  
  19.             //granted 用户接受授权 允许显示通知  
  20.             //denied  用户拒绝授权 不允许显示通知  
  21.   
  22.             console.log('permission: ' + permission);  
  23.         });  
  24.     },  
  25.     showNotification: function() {  
  26.         if (!this.isNotificationSupported) {  
  27.             console.log('the current browser does not support Notification API');  
  28.             return;  
  29.         }  
  30.         if (!this.isPermissionGranted()) {  
  31.             console.log('the current page has not been granted for notification');  
  32.             return;  
  33.         }  
  34.   
  35.         var n = new Notification("sir, you got a message", {  
  36.             icon: 'img/icon.png',  
  37.             body: 'you will have a meeting 5 minutes later.'  
  38.         });  
  39.   
  40.         //onshow函数在消息框显示时会被调用  
  41.         //可以做一些数据记录及定时操作等  
  42.         n.onshow = function() {  
  43.             console.log('notification shows up');  
  44.             //5秒后关闭消息框  
  45.             setTimeout(function() {  
  46.                 n.close();  
  47.             }, 5000);  
  48.         };  
  49.   
  50.         //消息框被点击时被调用  
  51.         //可以打开相关的视图,同时关闭该消息框等操作  
  52.         n.onclick = function() {  
  53.             alert('open the associated view');  
  54.             //opening the view...  
  55.             n.close();  
  56.         };  
  57.   
  58.         //当有错误发生时会onerror函数会被调用  
  59.         //如果没有granted授权,创建Notification对象实例时,也会执行onerror函数  
  60.         n.onerror = function() {  
  61.             console.log('notification encounters an error');  
  62.             //do something useful  
  63.         };  
  64.   
  65.         //一个消息框关闭时onclose函数会被调用  
  66.         n.onclose = function() {  
  67.             console.log('notification is closed');  
  68.             //do something useful  
  69.         };  
  70.     }  
  71. };  
  72.   
  73. document.addEventListener('load'function() {  
  74.     //try to request permission when page has been loaded.  
  75.     NotificationHandler.requestPermission();  
  76. });  

我们看到,上面代码创建了一个NotificationHandler的对象,来管理消息相关的事件逻辑,通常我们的流程是这样的:在页面加载完之后调用requestPermission函数请求用户授权,然后页面代码执行一段时间之后,需要显示一个消息时,再调用showNotification函数显示这个消息,例如:

[javascript] view plain copy
  1. setTimeout(function() {  
  2.     //if there has new mail, show notification  
  3.     NotificationHandler.showNotification();  
  4. }, 5000);  
需要注意的是,并不是所有的浏览器都支持Notification的,所以我们添加了一个isNotificationSupported属性,用来识别消息通知是否被浏览器所支持,在上面的代码中,如果识别到浏览器不支持这个API,就直接返回了,当然在实际的开发中,我们可以选择用其他形式来提醒用户。

然后我们来看一下index.html文件:

[javascript] view plain copy
  1. <!DOCTYPE html>  
  2. <html>  
  3.     <body>  
  4.         <button onclick="NotificationHandler.showNotification()">show notification</button>  
  5.     </body>  
  6.     <script type="text/javascript" src="js/main.js"></script>  
  7. </html>  
这个文件是极其简单的,也是比较直接的,就无需多说了,最后让我们来看一下实际的效果吧。

1. 点击按钮,弹出消息,然后直接关闭,或等待5秒钟,控制台会打印如下消息:

HTML5新特性之Web Notifications

2. 点击按钮,弹出消息,然后点击消息内容,弹出框会弹出:

HTML5新特性之Web Notifications

看上去还不错。在实际开发中,可能应用的比较复杂,但只要了解基本运行方式,一切都会变得简单起来的。

最后,需要注意的是,消息通知只有通过Web服务访问该页面时才会生效,如果直接双击打开本地文件,是没有任何效果的。所以在平时做练习的时候也需要把文件目录放进Web容器内,切记。

消息通知是个不错的特性,可是也不排除有些站点恶意的使用这个功能,一旦用户授权之后,不时的推送一些不太友好的消息,打扰用户的工作,这个时候我们可以移除该站点的权限,禁用其消息通知功能。我们可以依次点击设置打开设置的选项卡,然后点击底部的显示高级设置,在隐私一项中点击内容设置,最后会弹出一个内容面板,向下滑动找到消息通知一项,如何更改,想必就不用多说了。

讲到这里,关于消息通知的基本应用也就涵盖个差不多了,希望朋友们能仔细体会,最后可以把这个新特性应用在实际项目中,必定会增色不少的。