【PWA學習】5. 使用 Notification API 來進行消息提醒

引言

在上一節(jié), 介紹了如何使用 Push API 進行服務端消息推送。提到 Push 就不得不說與其聯(lián)系緊密的另一個 API——Notification API。它讓我們可以在“網(wǎng)站外”顯示消息提示:

消息推送示例

即使當你切換到其他 Tab,也可以通過提醒交互來快速讓用戶回到你的網(wǎng)站;甚至當用戶離開當前網(wǎng)站,仍然可以收到系統(tǒng)的提醒消息,并且可以通過消息提醒快速打開你的網(wǎng)站

交互示例

Notification 的功能本身與 Push 并不耦合,你完全可以只使用 Notification API 或者 Push API 來構(gòu)建 Web App的某些功能。因此,本文會先介紹如何使用 Notification API。然后,作為Notification的“黃金搭檔”,本文還會介紹如何組合使用 Push & Notification(消息推送與提醒)

使用Notification API

獲取提醒權(quán)限

在調(diào)用 Notification 相關API之前,需要先使用Notification對象上的靜態(tài)方法Notification.requestPermission()來獲取授權(quán):

// 申請桌面通知權(quán)限
function requestNotificationPermission() {
  // 系統(tǒng)不支持桌面通知
  if (!window.Notification) {
    return Promise.reject('系統(tǒng)不支持桌面通知')
  }
  return Notification.requestPermission().then(function (permission) {
    if (permission === 'granted') {
      return Promise.resolve()
    }
    return Promise.reject('用戶已禁止桌面通知權(quán)限')
  })
}

我們創(chuàng)建了一個requestNotificationPermission()方法來統(tǒng)一Notification.requestPermission()的調(diào)用形式,并在 Service Worker 注冊完成后調(diào)用該方法。調(diào)用Notification.requestPermission()獲取的permissionResult可能的值為:

  • denied:用戶拒絕了通知的顯示
  • granted:用戶允許了通知的顯示
  • default:因為不知道用戶的選擇,所以瀏覽器的行為與denied時相同

chrome 中,可以在 chrome://settings/content/notifications 里進行通知的設置與管理

設置提醒內(nèi)容

獲取用戶授權(quán)后,我們就可以通過registration.showNotification()方法進行消息提醒了

當我們注冊完 Service Worker 后,then方法的回調(diào)函數(shù)會接收一個registration參數(shù),通過調(diào)用其上的showNotification()方法即可觸發(fā)提醒:

// 監(jiān)聽 push 事件
self.addEventListener('push', function (e) {
  const { data } = e

  if (!data) return

  // 解析獲取推送消息
  let payload = data.json()
  // 根據(jù)推送消息生成桌面通知并展現(xiàn)出來
  let title = payload.title
  let options = {
    body: payload.body || '新消息',
    icon: payload.icon || '/img/icons/book-128.png',
    data: {
      url: payload.url,
    },
    actions: [
      {
        action: 'browse',
        title: '去看看',
      },
      {
        action: 'contact-me',
        title: '聯(lián)系我',
      },
    ],
    tag: 'pwa-starter',
    renotify: true,
  }
  let promise = self.registration.showNotification(title, options)

  e.waitUntil(promise)
})

title用來設置該提醒的主標題,option 中則包含了一些其他設置

  • body:提醒的內(nèi)容
  • icon:提醒的圖標
  • actions:提醒可以包含一些自定義操作
  • tag:相當于是ID,通過該ID標識可以操作特定的 notification
  • renotify:是否允許重復提醒,默認為 false。當不允許重復提醒時,同一個 tag 的 notification 只會顯示一次
彈窗示例

注: 由于不同瀏覽器中,對于 option 屬性的支持情況并不相同。部分屬性在一些瀏覽器中并不支持

捕獲用戶的點擊

在上一部分中,我們已經(jīng)為 Web App 添加了提醒功能。然而更多的時候,我們并不僅僅希望只展示有限的信息,更希望能引導用戶進行交互。例如推薦一本新書,讓用戶點擊閱讀或購買。

在上一部分我們設置的提醒框中,包含了“去看看”和“聯(lián)系我”兩個按鈕選項,那么怎么做才能捕獲用戶的點擊操作,并且知道用戶點擊了哪個呢?

還記的上一部分里我們定義的 actions 么?

[
  {
    action: 'browse',
    title: '去看看',
  },
  {
    action: 'contact-me',
    title: '聯(lián)系我',
  },
]

為了能夠響應用戶對于提醒框的點擊事件,我們需要在 Service Worker 中監(jiān)聽notificationclick事件。在該事件的回調(diào)函數(shù)中我們可以獲取點擊的相關信息:

// 監(jiān)聽通知點擊事件
self.addEventListener('notificationclick', function (e) {
  console.log('用戶點擊: ', e.action)
})

e.action就是我們在showNotification()中定義的 actions 里的 action 屬性, 可用它來判斷用戶點擊的是什么

注: 當用戶點擊提醒本身時,也會觸發(fā)notificationclick,但是不包含任何 action 值,所以在代碼中將其置于 default 默認操作中

示例

消息推送與提醒

到目前為止,我們已經(jīng)可以順利得給用戶展示提醒,并且在用戶操作提醒后準確捕獲到用戶的操作。然而,還缺最重要的一步——針對不同的操作,觸發(fā)不同的交互。例如:

  • 點擊“看一看”會跳轉(zhuǎn)到對應頁面
  • 點擊“聯(lián)系我”會向應用管理者發(fā)郵件等等
// 監(jiān)聽通知點擊事件
self.addEventListener('notificationclick', function (e) {
  const { notification = {}, action } = e
  const { data = {} } = notification
  const { url = '' } = data

  console.log('用戶點擊: ', action)
  // 關閉窗口
  e.notification.close()
  // 打開網(wǎng)頁
  if (action === 'contact-me') {
    e.waitUntil(clients.openWindow('mailto:shenxh0928@gmail.com'))
  } else {
    e.waitUntil(
      // 獲取所有clients
      self.clients.matchAll().then(function (clientsList) {
        // 切換到該站點的tab
        clientsList &&
          clientsList.length &&
          clientsList[0].focus &&
          clientsList[0].focus()

        self.clients.openWindow(url)
      }),
    )
  }
})

當用戶點擊提醒后,我們通過notificationclick監(jiān)聽,使用e.waitUntil(clients.openWindow(url))實現(xiàn)不同的操作

至此,一個比較簡單的消息提醒(Notification)功能就完成了

兼容性

看一下Web Notification 兼容性

Web Notification 兼容性

目前移動端瀏覽器普遍還不支持該特性,但是在 Mac OS 上的 safari 里面是支持該特性的,不過其調(diào)用方式與上文代碼有些不太一樣。在 safari 中使用 Web Notification 不是調(diào)用registration.showNotification()方法,而是需要創(chuàng)建一個 Notification 對象。

// 監(jiān)聽 push 事件
self.addEventListener('push', function (e) {
  const { data } = e

  if (!data) return

  // 解析獲取推送消息
  let payload = data.json()
  // 根據(jù)推送消息生成桌面通知并展現(xiàn)出來
  let title = payload.title
  let options = {
    body: payload.body || '新消息',
    icon: payload.icon || '/img/icons/book-128.png',
    data: {
      url: payload.url,
    },
    actions: [
      {
        action: 'browse',
        title: '去看看',
      },
      {
        action: 'contact-me',
        title: '聯(lián)系我',
      },
    ],
    tag: 'pwa-starter',
    renotify: true,
  }
  let notification = new Notification(title, options)

  notification.addEventListener('click', function (e) {
    console.log(e)
  })
})

本章分支: notification

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容