JS實現Web應用或網站傳送瀏覽器Notification通知

十方發表於2022-06-21

在開發一個Web應用系統或者一個網站時,當使用者觸發了某個事件,或者系統想通知使用者某個事件,比如有一條新的訊息、其他人點贊或者評論了文章、系統流程被稽核通過了等等諸如此類的場景,通常可能會想到 應用內通知 的方式,但是這種方式有一個侷限,就是如果使用者切換到瀏覽器其他頁籤或者其他應用程式時,可能無法及時看到應用系統的通知,那麼這個時候就可以藉助於瀏覽器的 Notification 通知功能了。

1、什麼是瀏覽器的 Notification

Notification 是瀏覽器提供的一種允許網頁向使用者顯示系統通知的機制,這種系統通知是在頂級瀏覽上下文視口之外,因此即使使用者已經切換標籤頁或移動到不同的應用程式,也可以顯示,並且 Notification 相關的 API 被設計成與不同平臺上的現有通知系統相容。

首先來看看瀏覽器的 Notification 通知是什麼樣的,這裡以 SegmentFault 網站為例,只要有新使用者關注或者文章被點贊收藏,SegmentFault 網站都會自動傳送 Notification 通知(能看到通知的前提是要允許網站傳送通知),具體通知如下:

除了 SegmentFault 網站外,還可以看看網頁版微信的系統通知,也是類似的。

2、如何使用 Notification

要顯示一個系統通知,一般需要分成兩步:使用者授予顯示通知的許可權傳送系統通知

(1)使用者授予顯示通知的許可權

系統要給使用者傳送通知,如果使用者不想檢視這個通知,即沒有授予相應的許可權,那麼即使通知發出了,使用者也是無法看到的。

如何向使用者詢問是否允許檢視系統通知的許可權呢?可以使用下面的方法

Notification.requestPermission()

該方法的返回值有三個:granteddenieddefault,最新的規範已將此方法更新為基於 promise 的語法,工作原理如下:

Notification.requestPermission().then(function(permission) { ... });

下面來看一個具體的例項,在 localhost 上詢問顯示系統通知的許可權,根據不同的選擇結果,列印相應的日誌資訊,程式碼如下:

Notification.requestPermission().then(function(result) {
    if (result === 'denied') {
        console.log('拒絕顯示系統通知');
        return;
    }
    if (result === 'default') {
        console.log('預設');
        return;
    }
    console.log('允許顯示系統通知')
});

按下F12,開啟 Chrome 的控制檯,複製上面的程式碼

執行後,可以看到瀏覽器會彈出一個詢問框,如下:

不同的選擇,控制檯會輸出不同的結果

  • 允許:控制檯會輸出 允許顯示系統通知,如果選擇了允許,再次請求許可權時,不會再彈出選擇框,而是在控制檯直接輸出允許顯示系統通知;
  • 禁止:控制檯會輸出 拒絕顯示系統通知,如果選擇了拒絕,再次請求許可權時,不會再彈出選擇框,而是在控制檯直接輸出拒絕顯示系統通知;;
  • x關閉:控制檯會輸出 預設,如果直接關閉了,再次請求許可權時,依然會彈出選擇框;

選擇【允許】後,此時再點選位址列的資訊按鈕,可以看到通知已開啟了,如下:

如果不想顯示通知了,可以直接在此處關閉通知即可,也可以使用下面的語句來檢視當前使用者的授權情況,如下:

Notification.permission

執行後,輸出結果

'granted'

(2)傳送系統通知

當使用者允許顯示系統通知後,就可以傳送通知了,這時可以使用 Notification() 建構函式建立一個新通知,這個方法可以傳入兩個引數,具體如下:

title(必傳)

  • 定義一個通知的標題,當它被觸發時,它將顯示在通知視窗的頂部。

options(可選)

options 物件包含應用於通知的任何自定義設定選項,常用的選項有:

  • dir : 文字的方向;它的值可以是 auto(自動), ltr(從左到右), or rtl(從右到左);
  • lang: 指定通知中所使用的語言。這個字串必須在 BCP 47 language tag 文件中是有效的;
  • body: 通知中額外顯示的字串;
  • tag: 賦予通知一個 ID,以便在必要的時候對通知進行重新整理、替換或移除;
  • icon: 一個圖片的 URL,將被用於顯示通知的圖示;

除了上述5個常用選項外,還有其他的 badgeimagedatavibraterenotifyrequireInteraction 等,具體可檢視官方網站的介紹 https://developer.mozilla.org/zh-CN/docs/Web/API/notification/Notification

下面來測試一個簡單的通知,程式碼如下:

let notification = new Notification('有一條新通知');

這個通知只有標題,執行後,可以看到

增加一些 options 選項,再次來測試一下系統通知,修改後的程式碼如下:

let notification = new Notification('有一條新通知', {
    dir: 'ltr',
    lang: 'zh-CN',
    body: '通知的正文內容:你的請假流程已批准',
    icon: 'http://localhost/coder/favicon.ico'
});

執行後,可以看到通知如下

(3)通知事件

Notification 通知有四種事件,可以通過監聽通知事件來執行不同的操作,具體事件如下:

  • Notification.onclick:對 click 事件的處理,每當使用者點選通知時被觸發;
  • Notification.onshow:對 show 事件的處理,當通知顯示的時候被觸發;
  • Notification.onerror:對 error 事件的處理,每當通知遇到錯誤時被觸發;
  • Notification.onclose:對 close 事件的處理,當使用者關閉通知時被觸發。

下面來測試一下通知事件的監聽,程式碼如下:

let notification = new Notification('有一條新通知', {
    dir: 'ltr',
    lang: 'zh-CN',
    body: '通知的正文內容:你的請假流程已批准',
    icon: 'http://localhost/coder/favicon.ico'
});

// 監聽通知顯示事件
notification.onshow = () => console.log('通知已顯示');

// 監聽通知點選事件
notification.onclick = () => console.log('通知被點選');

// 監聽通知被關閉事件
notification.onclose = () => console.log('通知被關閉');

// 監聽通知錯誤事件
notification.onerror = () => console.log('通知出現錯誤');

執行時,控制檯會直接輸出如下資訊

通知已顯示

點選通知時,會輸出

通知被點選

當通知關閉時,會輸出

通知被關閉

3、傳送Notification通知程式碼

結合上面的介紹,下面給出傳送通知的參考程式碼,具體如下:

function sendNotification(title, body, icon, callback) {
    // 先檢查瀏覽器是否支援
    if (!('Notification' in window)) {
        // IE瀏覽器不支援傳送Notification通知!
        return;
    }
    
    if (Notification.permission === 'denied') {
        // 如果使用者已拒絕顯示通知
        return;
    }
    
    if (Notification.permission === 'granted') {
        //使用者已授權,直接傳送通知
        notify();
    } else {
        // 預設,先向使用者詢問是否允許顯示通知
        Notification.requestPermission(function(permission) {
            // 如果使用者同意,就可以直接傳送通知
            if (permission === 'granted') {
                notify();
            }
        });
    }

    function notify() {
        let notification = new Notification(title, {
            icon: icon,
            body: body
        });
        notification.onclick = function() {
            callback && callback();
            console.log('單擊通知框')
        }
        notification.onclose = function() {
            console.log('關閉通知框');
        };
    }
}

下面來測試一下:

sendNotification('下班通知', '今天週五,還有十分鐘下班', 'http://localhost/coder/favicon.ico');

執行後,通知的效果如下:

參考資料:

相關文章