1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
---
title: 使用 Web Notifications
slug: Web/API/Notifications_API/Using_the_Notifications_API
translation_of: Web/API/Notifications_API/Using_the_Notifications_API
---
<p>{{SeeCompatTable}}</p>
<h2 id="摘要">摘要</h2>
<p>Web Notifications API 可將通知傳送至頁面以外的系統層級並顯示通知。因此即使 Web Apps 處於閒置狀態,亦可傳送資訊予使用者。絕佳範例之一,就是在使用其他 Apps 時,Web Mail App 同樣可通知使用者已接收到新郵件。</p>
<h2 id="要求權限">要求權限</h2>
<h3 id="網頁內容">網頁內容</h3>
<p>在 Apps 傳送通知之前,使用者必須先許可 Apps 的動作。只要 APIs 嘗試予網頁之外的東西互動,均必須先獲得使用者的授權。如此可避免濫發通知而影響使用經驗。</p>
<p>透過 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.permission" title="The permission property indicates the current permission granted by the user about web notification for the current application."><code>Notification.permission</code></a> 唯讀屬性,要傳送通知的 Apps 將檢查目前的授權狀態。此屬性共有 3 組參數:</p>
<ul>
<li><code>default:</code>使用者尚未給予任何權限 (因此不會顯示任何通知)</li>
<li><code>granted</code>:使用者允許接收到 Apps 的通知</li>
<li><code>denied</code><code>:使用者拒絕接收 </code>Apps 的通知</li>
</ul>
<div class="note">
<p><strong>注意:</strong>Chrome 與 Safari 尚未建構 <code>permission</code> 屬性。</p>
</div>
<p>若使用者尚未給予權限,則 Apps 必須透過 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.requestPermission" title="The requestPermission static method is used to ask the user for his permission to display a Notification to him."><code>Notification.requestPermission()</code></a> 函式讓使用者選擇,接著由此函式接收 1 組回呼 (Callback) 函式作為參數;而該回呼函式則提供使用者是否授權的資訊。</p>
<p>以下為啟動 Apps 時要求權限的常用範例:</p>
<pre class="brush: js">window.addEventListener('load', function () {
Notification.requestPermission(function (status) {
// This allows to use Notification.permission with Chrome/Safari
if (Notification.permission !== status) {
Notification.permission = status;
}
});
});</pre>
<div class="note">
<p><strong>注意:</strong>Chrome 不允許於載入事件中呼叫 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.requestPermission" title="The requestPermission static method is used to ask the user for his permission to display a Notification to him."><code>Notification.requestPermission()</code></a> (參閱 <a href="https://code.google.com/p/chromium/issues/detail?id=274284" title="https://code.google.com/p/chromium/issues/detail?id=274284">issue 274284</a>)。</p>
</div>
<h3 id="已安裝的_Apps">已安裝的 Apps</h3>
<p>在安裝 Apps 之後,若於 <a href="https://developer.mozilla.org/zh-TW/docs/%E6%87%89%E7%94%A8%E7%A8%8B%E5%BC%8F/Manifest-840092-dup" title="/en-US/docs/Web/Apps/Manifest">Apps 的 manifest 檔案</a>中直接添加權限,即可省去再次向使用者要求權限的動作。</p>
<pre class="brush: json">permissions: {
"desktop-notification": {
"description: "Allows to display notifications on the user's desktop.
}
}</pre>
<h2 id="建立通知">建立通知</h2>
<p>透過 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification" title="The Notification object is used to configure and display desktop notifications to the user."><code>Notification</code></a> 建構子 (Constructor) 即可建立通知。此建構子包含 1 組標題,可於通知內顯示;另有如 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.icon" title="The icon property indicates the URL of the icon to use with the notification."><code>icon</code></a> 或文字 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.body" title="The body property represents the text content of the body of the notification."><code>body</code></a><code> 等</code>數個選項,可強化通知的內容。</p>
<p>在建立實體 (Instantiated) 之後,就會儘快顯示通知。若要追蹤通知的目前狀態,必須在 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification" title="The Notification object is used to configure and display desktop notifications to the user."><code>Notification</code></a> 的實體階層觸發 4 個事件:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Reference/Events/show" title="/en-US/docs/Web/Reference/Events/show">show</a>:對使用者顯示通知之後,隨即觸發</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Reference/Events/click" title="/en-US/docs/Web/Reference/Events/click">click</a>:使用者點擊通知之後,隨即觸發</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Reference/Events/close" title="/en-US/docs/Web/Reference/Events/close">close</a>:關閉通知之後,隨即觸發</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Reference/Events/error" title="/en-US/docs/Web/Reference/Events/error">error</a>:通知發生任何錯誤 (大多數是因為某種情況而未顯示通知),隨即觸發</li>
</ul>
<p>而透過 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.onshow" title="Specifies an event listener to receive show events. These events occur when a Notification is displayed."><code>onshow</code></a>、<a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.onclick" title="Specifies an event listener to receive click events. These events occur when the user clicks on a displayed Notification."><code>onclick</code></a>、<a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.onclose" title="Specifies an event listener to receive close events. These events occur when a Notification is closed."><code>onclose</code></a>,或 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.onerror" title="Specifies an event listener to receive error events. These events occur when something goes wrong with a Notification (in many cases an error prevented the notification from being displayed)."><code>onerror</code></a> 等事件處理器 (Event handler),即可追蹤這些事件。由於 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification" title="The Notification object is used to configure and display desktop notifications to the user."><code>Notification</code></a> 是繼承 <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget" title="EventTarget is a DOM interface implemented by objects that can receive DOM events and have listeners for them."><code>EventTarget</code></a> 而來,因此亦可使用 <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener" title="addEventListener() registers the specified listener on the EventTarget it's called on. The event target may be an Element in a document, the Document itself, a Window, or any other object that supports events (such as XMLHttpRequest)."><code>addEventListener()</code></a> 函式。</p>
<div class="note">
<p><strong>注意:</strong>Firefox 與 Safari 並未遵守 close 事件的規格。此規格雖然規定「僅限使用者能關閉通知」,但 Firefox 與 Safari 卻可於數分鐘後自動關閉通知。因此不一定是由使用者關閉通知。</p>
<p>此規格並明確規定「應透過 <a href="https://developer.mozilla.org/en-US/docs/Web/API/Notification.close" title="The close method is used to close a Notification that has been displayed."><code>Notification.close()</code></a> 函式,於應用程式層級完成自動關閉通知」。範例程式碼如下:</p>
<pre class="brush: js">var n = new Notification("Hi!");
n.onshow = function () {
setTimeout(n.close, 5000);
}
</pre>
</div>
<h3 id="簡易範例">簡易範例</h3>
<p>先假設下列基本 HTML:</p>
<pre class="brush: html"><button>Notify me!</button></pre>
<p>則能以這種方法處理通知:</p>
<pre class="brush: js">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!");
}
});
});</pre>
<h3 id="現場測試結果">現場測試結果</h3>
<p>若無法顯示,可至本文右上角「Language」切換回英文原文觀看。</p>
<p>{{ EmbedLiveSample('Simple_example', '100%', 30) }}</p>
<h2 id="處理多筆通知">處理多筆通知</h2>
<p>某些情況下 (如某個即時訊息 App 持續通知每一筆進來的訊息),使用者可能會接收大量的通知。為了避免太多非必要訊息擠爆使用者的桌面,則應該讓等待中的通知進入佇列。</p>
<p>將標籤添加至任何新的通知,即可達到佇列效果。若通知擁有相同的標籤且尚未顯示,則新通知就會取代先前的通知;反之,若已顯示了相同標籤的通知,就會關閉先前的通知而顯示新通知。</p>
<h3 id="標籤範例">標籤範例</h3>
<p>先假設下列基本 HTML:</p>
<pre class="brush: html"><button>Notify me!</button></pre>
<p>則能以下列方式處理多筆通知:</p>
<pre class="brush: js">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!");
}
});
});</pre>
<h3 id="現場測試結果_2">現場測試結果</h3>
<p>若無法顯示,可至本文右上角「Language」切換回英文原文觀看。</p>
<p>{{ EmbedLiveSample('Tag_example', '100%', 30) }}</p>
<h2 id="規格">規格</h2>
<table class="standard-table">
<thead>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{SpecName('Web Notifications')}}</td>
<td>{{Spec2('Web Notifications')}}</td>
<td>Initial specification.</td>
</tr>
</tbody>
</table>
<h2 id="瀏覽器相容性">瀏覽器相容性</h2>
<p>{{page("/en-US/Web/API/Notification","Browser compatibility")}}</p>
<h2 id="另可參閱">另可參閱</h2>
<ul>
<li>{{ domxref("Notification") }}</li>
</ul>
|