-
前言
-
在 iOS 和 Android 移動設備中,Native App 向用戶推送通知是很常見的行爲,這是重新吸引用戶訪問應用最有效方法之一。然而推送通知一直被認爲是 Web App 缺少的能力,
-
申請通知權限
-
爲避免網站濫用 Notification 給用戶造成影響,在展示桌面通知之前,首先需要向用戶獲取通知權限,只有獲得用戶授權之後,Notification API 纔會生效。
-
Notification.permission
-
Notification.permission 是 Notification 的靜態屬性,代表通知權限的授權狀態,取值包括:、
- granted:允許展現通知;
- denied:禁止展現通知;
- default:用戶尚未授權,此時禁止展現通知,但可以向用戶發送授權申請
/*
* 然後你就可以處理你的業務需求
*/
function main () {
if (typeof Notification === 'undefined') {
console.log(`瀏覽器不支持 Notification`)
return
}
if (Notification.permission === 'denied') {
console.log(`Notification 權限已被禁用`)
return
}
if (Notification.permission === 'granted') {
console.log(`Notification 可用`)
} else {
Notification.requestPermission().then(function (permission) {
if (permission === 'granted') {
console.log(`用戶已授權,可展示通知`)
} else if (Notification.permission === 'denied') {
console.log(`用戶已禁止`)
} else {
console.log(` 用戶尚未授權,需首先向用戶申請通知權限`)
}
})
}
}
-
Notification.requestPermission()
-
當用戶尚未進行授權時,可以通過 Notification.requestPermission() 靜態方法向用戶申請通知權限
-
例子看上面
-
通知展現與交互
- 例子
const title = 'Simple Title';
const options = {
body: 'Simple piece of body text.\nSecond line of body text :)',
data: { type: 'focus-or-open-window', a: 1, url: '/test' }
};
const notification = new Notification(title, options)
以上的問題其實都很好解決,MDN 上有很多配置可以去看一下,配置啥,圖標呀,圖片呀,標題呀,是否強制用戶交互呀,等等的操作都在MDN 有介紹,接下來的我覺得纔可以看看
-
ServiceWorker 線程中展現通知
- 不知道ServiceWorker 的肯定知道PWA吧,其實是一個東西,不過我今天並不講那個東西,我只是講一下,如何利用ServiceWorker 和 Notification配合,當有消息通知來之後,如果當你tab 不在當前頁面,就跳轉到 消息通知的頁面,案例可以去看一下 twitte
-
以下操作默認你已經看完上面的,並且已經配置好了 ServiceWorker 的一系列的東西
- 接下來以我做的項目爲例
function focusOrOpenWindow(event) {
const url = event.notification.data.url || '/';
const urlToOpen = new URL(url, self.location.origin).href;
const promiseChain = clients
.matchAll({
type: 'window',
includeUncontrolled: true
})
.then(windowClients => {
let matchingClient = null;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.url === urlToOpen) {
matchingClient = windowClient;
break;
}
}
if (matchingClient) {
return matchingClient.focus();
} else {
return clients.openWindow(urlToOpen);
}
});
event.waitUntil(promiseChain);
}
self.addEventListener('notificationclick', function(event) {
event.notification.close();
const type = (event.notification.data && event.notification.data.type) || '';
switch (type) {
case 'focus-or-open-window':
focusOrOpenWindow(event);
break;
default:
// NOOP
break;
}
});
- 然後接下來 再全局掛載,比如我的是global
if ('ServiceWorker' in window) {
navigator.serviceWorker
.register('service-worker.js')
.then(function(registration) {
console.log('Service worker successfully registered.');
})
.catch(function(err) {
console.error('Unable to register service worker.', err);
});
}
- 你可以直接複製過去用,不懂可以