這是一個實驗中的功能
此功能在某些瀏覽器尚在開發中,請參考兼容表格以得到不同瀏覽器用的前輟。
摘要
Web Notifications API 可將通知傳送至頁面以外的系統層級並顯示通知。因此即使 Web Apps 處於閒置狀態,亦可傳送資訊予使用者。絕佳範例之一,就是在使用其他 Apps 時,Web Mail App 同樣可通知使用者已接收到新郵件。
要求權限
網頁內容
在 Apps 傳送通知之前,使用者必須先許可 Apps 的動作。只要 APIs 嘗試予網頁之外的東西互動,均必須先獲得使用者的授權。如此可避免濫發通知而影響使用經驗。
透過 Notification.permission
唯讀屬性,要傳送通知的 Apps 將檢查目前的授權狀態。此屬性共有 3 組參數:
default:
使用者尚未給予任何權限 (因此不會顯示任何通知)granted
:使用者允許接收到 Apps 的通知denied
:使用者拒絕接收
Apps 的通知
注意:Chrome 與 Safari 尚未建構 permission
屬性。
若使用者尚未給予權限,則 Apps 必須透過 Notification.requestPermission()
函式讓使用者選擇,接著由此函式接收 1 組回呼 (Callback) 函式作為參數;而該回呼函式則提供使用者是否授權的資訊。
以下為啟動 Apps 時要求權限的常用範例:
window.addEventListener('load', function () { Notification.requestPermission(function (status) { // This allows to use Notification.permission with Chrome/Safari if (Notification.permission !== status) { Notification.permission = status; } }); });
注意:Chrome 不允許於載入事件中呼叫 Notification.requestPermission()
(參閱 issue 274284)。
已安裝的 Apps
在安裝 Apps 之後,若於 Apps 的 manifest 檔案中直接添加權限,即可省去再次向使用者要求權限的動作。
permissions: { "desktop-notification": { "description: "Allows to display notifications on the user's desktop. } }
建立通知
透過 Notification
建構子 (Constructor) 即可建立通知。此建構子包含 1 組標題,可於通知內顯示;另有如 icon
或文字 body
等
數個選項,可強化通知的內容。
在建立實體 (Instantiated) 之後,就會儘快顯示通知。若要追蹤通知的目前狀態,必須在 Notification
的實體階層觸發 4 個事件:
而透過 onshow
、onclick
、onclose
,或 onerror
等事件處理器 (Event handler),即可追蹤這些事件。由於 Notification
是繼承 EventTarget
而來,因此亦可使用 addEventListener()
函式。
注意:Firefox 與 Safari 並未遵守 close 事件的規格。此規格雖然規定「僅限使用者能關閉通知」,但 Firefox 與 Safari 卻可於數分鐘後自動關閉通知。因此不一定是由使用者關閉通知。
此規格並明確規定「應透過 Notification.close()
函式,於應用程式層級完成自動關閉通知」。範例程式碼如下:
var n = new Notification("Hi!"); n.onshow = function () { setTimeout(n.close, 5000); }
簡易範例
先假設下列基本 HTML:
<button>Notify me!</button>
則能以這種方法處理通知:
window.addEventListener('load', function () { // At first, let's check if we have permission for notification // If not, let's ask for it 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 () { // If the user agreed to get notified if (Notification && Notification.permission === "granted") { var n = new Notification("Hi!"); } // If the user hasn't told if he wants to be notified or not // Note: because of Chrome, we are not sure the permission property // is set, therefore it's unsafe to check for the "default" value. else if (Notification && Notification.permission !== "denied") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } // If the user said okay if (status === "granted") { var n = new Notification("Hi!"); } // Otherwise, we can fallback to a regular modal alert else { alert(Hi!"); } }); } // If the user refuses to get notified else { // We can fallback to a regular modal alert alert(Hi!"); } }); });
現場測試結果
若無法顯示,可至本文右上角「Language」切換回英文原文觀看。
處理多筆通知
某些情況下 (如某個即時訊息 App 持續通知每一筆進來的訊息),使用者可能會接收大量的通知。為了避免太多非必要訊息擠爆使用者的桌面,則應該讓等待中的通知進入佇列。
將標籤添加至任何新的通知,即可達到佇列效果。若通知擁有相同的標籤且尚未顯示,則新通知就會取代先前的通知;反之,若已顯示了相同標籤的通知,就會關閉先前的通知而顯示新通知。
標籤範例
先假設下列基本 HTML:
<button>Notify me!</button>
則能以下列方式處理多筆通知:
window.addEventListener('load', function () { // At first, let's check if we have permission for notification // If not, let's ask for it 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 () { // If the user agreed to get notified // Let's try to send ten notifications if (Notification && Notification.permission === "granted") { for (var i = 0; i < 10; i++) { // Thanks to the tag, we should only see the "Hi! 10" notification var n = new Notification("Hi! " + i, {tag: 'soManyNotification'}); } } // If the user hasn't told if he wants to be notified or not // Note: because of Chrome, we are not sure the permission property // is set, therefore it's unsafe to check for the "default" value. else if (Notification && Notification.permission !== "denied") { Notification.requestPermission(function (status) { if (Notification.permission !== status) { Notification.permission = status; } // If the user said okay if (status === "granted") { for (var i = 0; i < 10; i++) { // Thanks to the tag, we should only see the "Hi! 10" notification var n = new Notification("Hi! " + i, {tag: 'soManyNotification'}); } } // Otherwise, we can fallback to a regular modal alert else { alert(Hi!"); } }); } // If the user refuses to get notified else { // We can fallback to a regular modal alert alert(Hi!"); } }); });
現場測試結果
若無法顯示,可至本文右上角「Language」切換回英文原文觀看。
規格
Specification | Status | Comment |
---|---|---|
Web Notifications | Working Draft | Initial specification. |
瀏覽器相容性
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | 5 webkit (see notes) 22 |
4.0 moz (see notes) 22 |
Not supported | ? | 6 (see notes) |
Feature | Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
Basic support | ? | 4.0 moz (see notes) 22 |
Not supported | ? | ? |
Gecko notes
- Prior to Firefox 22 (Firefox OS <1.2), the instantiation of a new notification must be done with the
navigator.mozNotification
object through itscreateNotification
method. - Prior to Firefox 22 (Firefox OS <1.2), the Notification was displayed when calling the
show
method and was supporting theclick
andclose
events only. - Nick Desaulniers has written a Notification shim to cover both newer and older implementations.
- One particular Firefox OS issue is that you can pass a path to an icon to use in the notification, but if the app is packaged you cannot use a relative path like
/my_icon.png
. You also can't usenavigator.location.origin + "/my_icon.png"
becausenavigator.location.origin
is null in packaged apps. The manifest origin field fixes this, but it is only available in Firefox OS 1.1+. A potential solution for supporting Firefox OS <1.1 is to pass an absolute URL to an externally hosted version of the icon. This is less than ideal as the notification is displayed immediately with the icon missing, then the icon is fetched, but it works on all versions of Firefox OS.
Chrome notes
- Prior to Chrome 22, the support for notification was following an old prefixed version of the specification and was using the
navigator.webkitNotifications
object to instantiate a new notification. - Prior to Chrome 32,
Notification.permission
was not supported.
Safari notes
- Safari started supporting notification with Safari 6 but only on Mac OSX 10.8+ (Mountain Lion).