浅尝浏览器桌面通知 Notification

参考:

一、前言

最近业务开发中,有一个需求,需要弹出桌面通知弹窗。

这是我从没做过的,所以开贴与大家分享一下,另外讲一下存在的问题。

image.png

二、Notification

2.1 通知实例

new Notification(title)
new Notification(title, options)
  • title:标题
  • options:配置(可选)

2.2 通知的配置

也是弹窗的组成部分:

  • image 通知弹窗的上方大图
  • icon 图标
  • requireInteraction 下方的关闭按钮(默认值为 false)
  • silent 通知声音静音(默认值为 false)
  • body 通知内容

等等。

const options = {
  image: 'https://images.unsplash.com/photo-1623653387945-2fd25214f8fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80',
  // body 正文部分最多显示 4 行
  body: `here the body (the first line)\nthe second line\nthe third line\nthe fourth line\nthe fifth line which cannot display\n`,
  icon: 'https://images.unsplash.com/photo-1619380897562-725c909c68db?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80',
  // Indicates that a notification should remain active until the user clicks or dismisses it, rather than closing automatically.
  requireInteraction: true,
  silent: true
}

注意:

  • body 内容最多能显示 4 行。
  • image, icon 本地和远程的 url 都支持。
  • requireInteraction 默认为 false,会自动关闭通知。只有设置为 true 后,面板下方才能出现“关闭”按钮,此时监听通知的关闭事件才有效果;另外,设置为 true 后,这类弹窗无法自动关闭。
  • silent 默认为 false,设置为 true 后,就不会有系统提示音了,这个可以不用去系统里设置谷歌浏览器的通知声音,用这个属性就能解决。

三、可运行的代码

原功能比这个更加复杂,这里做了简化。

<!DOCTYPE html>
<html>
  <head>
    <title>浏览器通知</title>
  </head>
  <body>
    <button onclick="notifyMe()">Notify me!</button>
    <button onclick="mutiplyNotify()">Notify me! (mutiplyNotify)</button>

    <script>
      function generateNotification (title, options) {
        return new Notification(title, options)
      }

      function mutiplyNotify () {
        for (let i = 0; i < 3; i++) {
          notifyMe(i)
        }
      }

      function notifyMe(title = '') {
        console.log(title)
        let notification = null
        const options = {
          image: 'https://images.unsplash.com/photo-1623653387945-2fd25214f8fc?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80',
          // image: './bg.jpg',
          // body 正文部分最多显示 4 行
          body: `here the body (the first line)\nthe second line\nthe third line\nthe fourth line\nthe fifth line which cannot display\n`,
          icon: 'https://images.unsplash.com/photo-1619380897562-725c909c68db?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80',
          // icon: './th.jpg',
          // Indicates that a notification should remain active until the user clicks or dismisses it, rather than closing automatically.
          requireInteraction: true,
          silent: true
        }

        // Let's check if the browser supports notifications
        if (!("Notification" in window)) {
          alert("This browser does not support desktop notification");
        }

        // Let's check whether notification permissions have already been granted
        else if (Notification.permission === "granted") {
          // If it's okay let's create a notification
          notification = generateNotification(`Hi there! I'm a title${title}.`, options);
        }

        // Otherwise, we need to ask the user for permission
        else if (Notification.permission !== "denied") {
          Notification.requestPermission().then(function (permission) {
            // If the user accepts, let's create a notification
            if (permission === "granted") {
              notification = generateNotification(`Hi there! I'm a title${title}.`, options);
            }
          });
        }

        // At last, if the user has denied notifications, and you
        // want to be respectful there is no need to bother them anymore.

        // when show
        notification.onshow = function () {
          console.log('when show')
        }
        // when click
        notification.onclick = function () {
          console.log('when click')
          window.open(window.location.href)
        }
        // when close
        notification.onclose = function () {
          console.log('when close')
        }
        // when error
        notification.onerror = function () {
          console.log('when error')
        }
      }
    </script>
  </body>
</html>

四、总结与风险点评估

Notification 将浏览器 API 与 windows 通知功能结合,作为通知用户的一种方式显得非常巧妙,仅仅是通知也比较合适。但过度的定制化,开发性价比是不高的,存在一些问题尚未解决或难以解决。

  1. 一次只能在右下角显示一个,无法叠加显示多个通知面板。

  2. 通过点击通知面板右上角的“x”图标关闭弹窗时,无法监听到点击事件、也无法监听到关闭事件。

  3. for循环依次新建通知面板时,通知面板的弹出顺序是乱序的,可能是因为线程不同导致的。 image.png

  4. 当用户将浏览器窗口最小化,想要实现点击通知回到原网页,似乎难以解决。

    但这里提供一个取巧的方案(developer.mozilla.org/zh-CN/docs/…),利用 window.open() 打开一个新标签页(newTab),然后立即再通过 window.close() 去关闭 newTab,让用户好像就回到了原网页一样。

    notification.onclick = function () {
      console.log('when click')
      window.open(window.location.href)
      const newTab = window.open(window.location.href)
      window.close('newTab')
    }
    
  5. 浏览器兼容性可能不太好

    image.png

  6. 为了确保安全,这个API只允许在 HTTPS 环境下使用,但是也可以通过特别的方式去设置,这里不赘述。

添加我的微信:enjoy_Mr_cat,共同成长,卷卷群里等你 🤪。

posted @ 2022-07-23 10:12  见嘉于世  阅读(0)  评论(0编辑  收藏  举报  来源