Skip to content
导航

Notification

Notification API 用于通过浏览器向用户发送桌面通知。

浏览器限制此API仅在HTTPS网页中可用,HTTP网页中不会出现通知。

通知分为两类用法:

  • 在网页中发出通知
  • 在Service Worker中发出通知 后者可以提供最大数量为Notification.maxActions个的选项,显示给用户操作通知

无论哪种通知,都需要经过浏览器向用户请求允许通知

请求允许通知

请求用户允许当前源(origin)的通知。

在得到允许后,当前源下的网页、Service Worker都能发出通知。

js
Notification.requestPermission().then(()=>{
  console.log(Notification.permission) // denied \ granted \ default
  //在这个回调里、回调执行后就能够发出通知
})

使用此功能时应总是先请求用户允许通知,有备无患,在需要发出通知时不再请求。

在网页中发送通知

API

js
new Notification(title, options)

用法

js
new Notification('hello') // 每次执行都会发出一个通知

new Notification(title, {
    body: '这是通知',
    icon: 'https://fecat.win/favicon.ico',
    tag: 'string', // 相当于ID。tag相同则覆盖通知

    dir: 'rtl', // Chrome忽略此配置
    lang: 'en-US', // Chrome忽略此配置
    badge: 'imgUrl', //Chrome不展示
    image: 'https://avatars.githubusercontent.com/u/12523415?v=4', //Chrome不展示
    data: {content: 'data'}, // 通知实例携带数据
    vibrate: [200, 100, 200], // 震动参数
    renotify: false, // tag相同覆盖时重新通知,是否有效受操作系统限制
    // requireInteraction: true, // 通知需要用户交互才收回。Chrome设置后不会发出通知
})

DEMO

在Service Worker中发出通知

API

js
// 发出通知,返回Promise
self.registration.showNotification(title, options)
// 查询通知的示例,返回Promise
self.registration.getNotifications(options)

self.addEventListener('notificationclick', handler)
self.addEventListener('notificationclose', handler)

用法

以下代码实现从service worker中主动发出通知,并在4s后主动关闭通知

js
if(Notification.permission === 'granted') {
  self.registration.showNotification('您有新的消息', {
    body: '快打开看看',
    actions: [
      { action: 'open', title: '打开' },
      { action: 'close', title: '关闭' },
    ],
  }).then(()=>{
    self.registration.getNotifications().then(list=>{
      // 4s后主动关闭通知
      setTimeout(()=>list.forEach(item=>item.close()), 4000)
    })
  })
}

以下代码处理通知action点击事件

js
self.addEventListener('notificationclick', (event) => {
  event.notification.close()
  if (event.action !== 'open') return

  event.waitUntil(
    clients
      .matchAll({
        type: 'window',
      })
      .then((clientList) => {
        for (const client of clientList) {
          // 激活页面
          if ('focus' in client) return client.focus()
        }
        // 打开页面
        if (clients.openWindow) {
          return clients.openWindow(
            self.registration.scope + 'notification.html'
          )
        }
      })
  )
})

DEMO

参考资料