Notification
是HTML5新增的API,用於向用戶配置和顯示桌面通知。上次在別的網站上看到別人的通知彈窗,好奇之餘也想知道如何實現的。實際去查一下發現並不複雜,且可以說比較簡單,故寫篇博客分享給大家,希望能幫你們瞭解這個API。
npm包:
我還發了一個npm包:notification-Koro1,非常輕量簡潔,覺得不錯的話,點個Star吧~
chrome下Notification
的表現:
- 以谷歌爲例,一開始需要用戶允許通知:
- 允許通知之後,顯示的通知長這樣:
Notification
特性
- 該通知是脫離瀏覽器的,即使用戶沒有停留在當前標籤頁,甚至最小化了瀏覽器,也會在主屏幕的右上角顯示通知,然後在一段時間後消失。
- 我們可以監聽通知的顯示,點擊,關閉等事件,比如點擊通知打開一個頁面。
博客、前端積累文檔、公衆號、GitHub
栗子:去各個網站裏面的控制檯去運行
API的具體細節,等下再說,先試試這個API~
下面是一個簡單的栗子,大家可以先在各個網站的控制檯裏面運行查看Notification
的效果:
var options = {
dir: "auto", // 文字方向
body: "通知:OBKoro1評論了你的朋友圈", // 通知主體
requireInteraction: true, // 不自動關閉通知
// 通知圖標
icon: "https://upload-images.jianshu.io/upload_images/5245297-818e624b75271127.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"
};
notifyMe('這是通知的標題', options);
function notifyMe(title, options) {
// 先檢查瀏覽器是否支持
if (!window.Notification) {
console.log('瀏覽器不支持通知');
} else {
// 檢查用戶曾經是否同意接受通知
if (Notification.permission === 'granted') {
var notification = new Notification(title, options); // 顯示通知
} else if (Notification.permission === 'default') {
// 用戶還未選擇,可以詢問用戶是否同意發送通知
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
console.log('用戶同意授權');
var notification = new Notification(title, options); // 顯示通知
} else if (permission === 'default') {
console.warn('用戶關閉授權 未刷新頁面之前 可以再次請求授權');
} else {
// denied
console.log('用戶拒絕授權 不能顯示通知');
}
});
} else {
// denied 用戶拒絕
console.log('用戶曾經拒絕顯示通知');
}
}
}
瀏覽器支持:
MDN:目前Notification
除了IE瀏覽器不支持外, 其他瀏覽器都已支持桌面通知,移動端瀏覽器基本都未支持。
因爲兼容性問題,所以在使用Notification
之前,我們需要查看瀏覽器是否支持Notification
這個API:
if(window.Notification){
// 桌面通知的邏輯
}
通知權限:
爲了避免網站濫用通知擾民,在向用戶顯示通知之前,需要經過用戶同意。
Notification.permission
用於表明當前通知顯示的授權狀態,它有三個值:
-
default
: 默認值,用戶還未選擇 -
granted
: 用戶允許該網站發送通知 -
denied
: 用戶拒絕該網站發送通知
檢測權限:
檢測瀏覽器是否支持Notification
之後,需要檢測一下用戶通知權限。
if (Notification.permission === 'granted') {
console.log('用戶曾經同意授權');
// 隨時可以顯示通知
} else if (Notification.permission === 'default') {
console.log('用戶還未選擇同意/拒絕');
// 下一步請求用戶授權
} else {
console.log('用戶曾經拒絕授權 不能顯示通知');
}
請求權限
當Notification.permission
爲default
的時候,我們需要使用Notification.requestPermission()
來請求用戶權限。
Notification.requestPermission()
基於promise語法,then的回調函數參數是用戶權限的狀態Notification.permission
的值。
Notification.requestPermission().then(permission => {
if (permission === 'granted') {
console.log('用戶同意授權');
// 隨時可以顯示通知
} else if (permission === 'default') {
console.log('用戶關閉授權 可以再次請求授權');
} else {
console.log('用戶拒絕授權 不能顯示通知');
}
});
// 老版本使用的是回調函數機制:Notification.requestPermission(callback); 參數一樣
推送通知
當Notification.permission
爲granted
時,請求到用戶權限之後,不必立即發送通知,可以在任意時刻,以任意形式來發送通知。
const options = {}; // 傳空配置
const title = '這裏是標題';
const notification = new Notification(title, options) // 顯示通知
上面這段代碼就可以顯示一個簡單的通知了,只要用戶允許你彈窗。
Notification
的參數:
- title:通知的標題
-
options:通知的設置選項(可選)。
requireInteraction: 保持通知不自動關閉
默認值爲false,通知會在三四秒之後自動關閉。
當設置爲true
,並且當有超過兩個通知(new Notification(title, options)
)時,會出現如下圖的通知疊加狀態。
這種情況顯然,我們只能默認操作最後一個通知,除非你把每個通知返回的實例都保存下來。
我發佈的npm包:notification-koro1,可以自定義一定的時間間隔自動關閉不自動關閉的通知,也可以一次性關閉所有通知
PS:如果沒有觸發疊加,很可能是因爲你兩次通知的tag配置項是相同的(相同tag只能出現一個彈窗)。
PS: safari下不支持該選項,默認自動關閉
renotify:相同
默認值爲false,chorme下相同tag的通知不替換,還是老的通知
設置爲true
, 兩個相同tag的通知,新通知替換之前舊的通知。
注意:使用renotify
,必須要同時設置tag
選項,否則將會報錯。
PS: safari下不支持該選項,默認兩個相同tag的通知,新通知替換之前舊的通知。
Notification
的實例:
生成通知,會返回一個實例,如下:
const instanceNotification = new Notification(title, options)
instanceNotification
就是當前通知的實例,在該實例上,我們可以查詢該通知的配置,監聽事件,調用實例方法。
下文都以instanceNotification
指代通知返回的實例。
通知的配置:
在通知實例上可以讀取到設置通知時的所有配置,比如:
通知標題:instanceNotification. title
、通知內容:instanceNotification. body
、通知圖標:instanceNotification. icon
等。
PS: 這些屬性都是隻讀的,不能刪除,不能修改,不能遍歷。
事件處理:
我們可以使用通知的實例來監聽通知的事件:
-
click
: 用戶點擊通知時被觸發 -
show
: 通知顯示的時候被觸發 -
error
: 通知遇到錯誤時被觸發 -
close
: 用戶關閉通知時被觸發
instanceNotification.onclick = e => {
// do something 可以是:打開網址,發請求,關閉通知等
}
注意:最好是一發出通知就立即監聽事件,否則有些事件可能一開始沒被觸發或永遠不會觸發。
例如:用定時器5秒後才監聽通知的點擊和顯示事件,則永遠不會觸發通知顯示的回調,點擊事件在5秒後纔可以正常起作用但會錯誤五秒之前用戶的點擊。
關閉通知
instanceNotification.close()
沒有設置不自動關閉的話,chrome通知將會在4.5秒左右自動關閉通知,safari則是5秒鐘(無法設置不自動關閉)。
notification沒有定時控制通知多久後消失的功能,當出現多個通知,也無法統一關閉。
這兩個問題,在我發佈的NPM包:notification-koro1中,都解決掉了,並提供更清晰的回調
應用場景
- 即時通訊軟件(郵件、聊天室)
- 體育賽事結果彩票/抽獎結果
- 新聞網站重大新聞通知
- 網站的重大更新,重大新聞等。
notification其他
這裏是一些API/瀏覽器細節,以及可能會遇到的問題,可以先不看,等真正遇到了,回頭再來看。
用戶拒絕顯示通知:
一旦用戶禁止網站顯示通知,網站就不能再請求用戶授權顯示通知,需要用戶去設置中更改。
chrome瀏覽器的通知設置位置:設置>高級>內容設置>通知
saafari瀏覽器:偏好設置>網站>通知>找到網站>修改權限/恢復默認
關閉請求權限:
在chorme瀏覽器中:當用戶關閉請求權限的彈窗(右上角的叉叉),頁面還沒刷新,我們可以再次向用戶請求權限。頁面刷新過後,瀏覽器默認用戶拒絕。
在safari瀏覽器下,沒有關閉請求權限的選項,用戶必須選擇同意/拒絕。
icon不顯示問題:
可能是網站進行了同源限制(比如github),不是域名下面的圖片,會報錯,不能調用。
tag:
-
tag
相同的通知,同時只能出現一個,老通知是否會被覆蓋取決於:renotify
配置和瀏覽器。 - chrome下:當通知關閉之後,上次出現過的tag在一段時間內,不能再出現,比如刷新頁面再請求相同tag的通知。(在safari下正常出現)
safari下面不能顯示icon
在safari下面,同一個網站(比如谷歌),同樣的代碼,chorme可以正常顯示icon,safari卻沒有icon,也沒有報錯。
谷歌之後發現,在stack overflow裏面看到safari只支持body和tag選項,並不支持icon選項。
連續觸發
在safari和chrome下短時間內連續觸發通知(不設tag
,不設requireInteraction
),會出現如下表現:
這個表現,通知沒有icon、標題、內容,就顯得沒有意義了,瀏覽器以這種形式,限制開發者不要頻繁打擾用戶。
notification-Koro1:
試一下notification-Koro1啦, 持續維護,簡單方便~
結語
本文寫的比較細,可以先mark一下,然後以後真正用到這個API了,可以先通過文中的栗子,然後再查找對應的內容。
還有就是注意瀏覽器間的差異,我自己就試了chrome和safari,然後這兩個瀏覽器在實現細節上有很多不一樣的地方,開發的時候注意一下。
參考資料: