H5 notification瀏覽器桌面通知

OBKoro1發表於2019-02-21

Notification是HTML5新增的API,用於向使用者配置和顯示桌面通知。上次在別的網站上看到別人的通知彈窗,好奇之餘也想知道如何實現的。實際去查一下發現並不複雜,且可以說比較簡單,故寫篇部落格分享給大家,希望能幫你們瞭解這個API。

npm包:

我還發了一個npm包:notification-Koro1,非常輕量簡潔,覺得不錯的話,點個Star吧~

chrome下Notification的表現:

  1. 以谷歌為例,一開始需要使用者允許通知:

H5 notification瀏覽器桌面通知

  1. 允許通知之後,顯示的通知長這樣:

H5 notification瀏覽器桌面通知

Notification特性

  1. 該通知是脫離瀏覽器的,即使使用者沒有停留在當前標籤頁,甚至最小化了瀏覽器,也會在主螢幕的右上角顯示通知,然後在一段時間後消失

  2. 我們可以監聽通知的顯示,點選,關閉等事件,比如點選通知開啟一個頁面。

部落格前端積累文件公眾號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 用於表明當前通知顯示的授權狀態,它有三個值:

  1. default: 預設值,使用者還未選擇
  2. granted: 使用者允許該網站傳送通知
  3. denied: 使用者拒絕該網站傳送通知

檢測許可權:

檢測瀏覽器是否支援Notification之後,需要檢測一下使用者通知許可權。

  if (Notification.permission === 'granted') {
    console.log('使用者曾經同意授權');
     // 隨時可以顯示通知
  } else if (Notification.permission === 'default') {
    console.log('使用者還未選擇同意/拒絕');
    // 下一步請求使用者授權
  } else {
    console.log('使用者曾經拒絕授權 不能顯示通知');
  }
複製程式碼

請求許可權

Notification.permissiondefault的時候,我們需要使用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.permissiongranted時,請求到使用者許可權之後,不必立即傳送通知,可以在任意時刻,以任意形式來傳送通知。

const options = {}; // 傳空配置
const title = '這裡是標題';
const notification = new Notification(title, options) // 顯示通知
複製程式碼

上面這段程式碼就可以顯示一個簡單的通知了,只要使用者允許你彈窗。

Notification的引數:

  • title:通知的標題
  • options:通知的設定選項(可選)。
    • body:字串。通知的body內容。
    • tag:代表通知的一個識別標籤,相同tag時只會開啟一個通知視窗
    • icon:字串。要在通知中顯示的圖示的URL。
    • data:想要和通知關聯的資料,可以在new Notification返回的例項中找到。
    • renotify: 布林值。相同tag,新通知出現的時候是否替換之前的(開啟此項,tag必須設定)。
    • requireInteraction:布林值。通知不自動關閉,預設為false(自動關閉)。
    • 還有一些不太重要的配置可以看張鑫旭老師的部落格MDN的介紹

requireInteraction: 保持通知不自動關閉

預設值為false,通知會在三四秒之後自動關閉。

當設定為true,並且當有超過兩個通知(new Notification(title, options))時,會出現如下圖的通知疊加狀態。

H5 notification瀏覽器桌面通知

這種情況顯然,我們只能預設操作最後一個通知,除非你把每個通知返回的例項都儲存下來。

我釋出的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:

  1. tag相同的通知,同時只能出現一個,老通知是否會被覆蓋取決於:renotify配置和瀏覽器。
  2. chrome下:當通知關閉之後,上次出現過的tag在一段時間內,不能再出現,比如重新整理頁面再請求相同tag的通知。(在safari下正常出現)

safari下面不能顯示icon

在safari下面,同一個網站(比如谷歌),同樣的程式碼,chorme可以正常顯示icon,safari卻沒有icon,也沒有報錯。

谷歌之後發現,在stack overflow裡面看到safari只支援body和tag選項,並不支援icon選項

連續觸發

在safari和chrome下短時間內連續觸發通知(不設tag,不設requireInteraction),會出現如下表現:

notification 連續觸發

這個表現,通知沒有icon、標題、內容,就顯得沒有意義了,瀏覽器以這種形式,限制開發者不要頻繁打擾使用者。

notification-Koro1:

試一下notification-Koro1啦, 持續維護,簡單方便~


結語

本文寫的比較細,可以先mark一下,然後以後真正用到這個API了,可以先通過文中的栗子,然後再查詢對應的內容。

還有就是注意瀏覽器間的差異,我自己就試了chrome和safari,然後這兩個瀏覽器在實現細節上有很多不一樣的地方,開發的時候注意一下。

希望看完的朋友可以點個喜歡/關注,您的支援是對我最大的鼓勵。

部落格前端積累文件公眾號GitHub

以上2019.02.17

參考資料:

notification-Koro1

簡單瞭解HTML5中的Web Notification桌面通知

Notification MDN

HTML5 桌面通知:Notification API

相關文章