显示通知

Alexey Rodionov
Alexey Rodionov
Matt Gaunt

通知选项分为两部分,一部分介绍视觉方面(本部分),另一部分介绍通知的行为方面(下一部分)。

您可以使用 Peter Beverloo通知生成器,在不同平台上的各种浏览器中试用各种通知选项。

视觉选项

用于显示通知的 API 很简单:

<ServiceWorkerRegistration>.showNotification(<title>, <options>);

titleoptions 都是可选参数。

标题是一个字符串,其选项可以是以下任意一种:

{
  "//": "Visual Options",
  "body": "<String>",
  "icon": "<URL String>",
  "image": "<URL String>",
  "badge": "<URL String>",
  "dir": "<String of 'auto' | 'ltr' | 'rtl'>",
  "timestamp": "<Long>"

  "//": "Both visual & behavioral options",
  "actions": "<Array of Strings>",
  "data": "<Anything>",

  "//": "Behavioral Options",
  "tag": "<String>",
  "requireInteraction": "<boolean>",
  "renotify": "<Boolean>",
  "vibrate": "<Array of Integers>",
  "sound": "<URL String>",
  "silent": "<Boolean>",
}

我们来看一下这些直观的选项:

对通知界面的剖析。

标题和正文选项

在 Windows 上的 Chrome 中,不包含标题和选项的通知如下所示:

Windows 版 Chrome 中不含标题和选项的通知。

如您所见,浏览器名称用作标题,“新通知”占位符用作通知正文。

如果设备上安装的是渐进式 Web 应用,系统将使用 Web 应用名称(而非浏览器名称):

包含 Web 应用名称(而非浏览器名称)的通知。

如果我们运行以下代码:

const title = 'Simple Title';

const options = {
  body: 'Simple piece of body text.\nSecond line of body text :)',
};

registration.showNotification(title, options);

我们会在 Linux 上的 Chrome 中收到此通知:

Linux 上的 Chrome 中显示带有标题和正文文本的通知。

在 Linux 上的 Firefox 中,此目录如下所示:

Linux 上的 Firefox 中带有标题和正文文本的通知。

在 Linux 上的 Chrome 中,标题和正文中包含大量文本的通知如下所示:

Linux 上的 Chrome 中显示包含长标题和正文的通知。

Linux 上的 Firefox 会收起正文文本,直到您将鼠标悬停在通知上,使通知展开:

Linux 上的 Firefox 中带有长标题和正文的通知。

在 Linux 上的 Firefox 中,用鼠标光标悬停在该通知上时,通知会带有长标题和正文文本。

Windows 版 Firefox 中的相同通知如下所示:

Windows 版 Firefox 中带有标题和正文文本的通知。

Windows 版 Firefox 中带有长标题和正文的通知。

如您所见,同一通知在不同浏览器中的外观可能会有所不同。同一浏览器在不同平台上的外观也可能会不同。

在适用的平台上,Chrome 和 Firefox 会使用系统通知和通知中心。

例如,macOS 上的系统通知不支持图片和操作(按钮和内嵌回复)。

Chrome 还提供适用于所有桌面平台的自定义通知。您可以通过将 chrome://flags/#enable-system-notifications 标志设置为 Disabled 状态来启用它。

Icon

icon 选项本质上是一种可以显示在标题和正文旁边的小图片。

在您的代码中,您需要提供一个要加载的图片的网址:

const title = 'Icon Notification';

const options = {
  icon: '/images/demos/icon-512x512.png',
};

registration.showNotification(title, options);

您会在 Linux 上的 Chrome 中收到此通知:

Linux 上的 Chrome 中带有图标的通知。

而在 Linux 上的 Firefox 中:

Linux 上的 Firefox 中带有图标的通知。

很抱歉,对于图标应采用多大尺寸的图片,并没有固有的准则。

Android 似乎需要 64dp 的图片(这是设备像素比的 64px 的倍数)。

假设设备的最高像素比为 3,那么大小为 192 像素或更大的图标就是稳妥的选择。

徽章

{0/} 是一个单色小图标,用于向用户{101}提供有关通知来源的更多信息:

const title = 'Badge Notification';

const options = {
  badge: '/images/demos/badge-128x128.png',
};

registration.showNotification(title, options);

在撰写本文时,该徽章仅用在 Android 版 Chrome 中。

Android 版 Chrome 中带有标志的通知。

在其他浏览器(或不带此徽章的 Chrome)上,您将看到该浏览器的图标。

Android 版 Firefox 中带有标志的通知。

icon 选项一样,对于应使用何种尺寸,并没有真正的准则。

请参阅 Android 指南,建议的尺寸为 24 像素乘以设备像素比。

也就是说,像素不低于 72 像素的图片应该效果不错(假设设备的最大像素比为 3)。

映像

image 选项可用于向用户显示更大的图片。这对于向用户显示预览图片特别有用。

const title = 'Image Notification';

const options = {
  image: '/images/demos/unsplash-farzad-nazifi-1600x1100.jpg',
};

registration.showNotification(title, options);

在 Linux 上的 Chrome 中,通知将如下所示:

Linux 上的 Chrome 中带有图片的通知。

在 Android 版 Chrome 中,剪裁和比例有所不同:

Android 版 Chrome 中带有图片的通知。

鉴于桌面设备和移动设备的比率存在差异,我们很难提出指南。

由于桌面版 Chrome 不会填满可用空间且宽高比为 4:3,因此最佳方法是以该宽高比提供图片,并允许 Android 剪裁图片。尽管如此,image 选项仍可能会更改。

在 Android 设备上,唯一的准则是 450dp 的宽度。

根据这条指导原则,最好使用宽度不小于 1350 像素的图片。

操作(按钮)

您可以定义 actions 来显示按钮和通知:

const title = 'Actions Notification';

const options = {
  actions: [
    {
      action: 'coffee-action',
      type: 'button',
      title: 'Coffee',
      icon: '/images/demos/action-1-128x128.png',
    },
    {
      action: 'doughnut-action',
      type: 'button',
      title: 'Doughnut',
      icon: '/images/demos/action-2-128x128.png',
    },
    {
      action: 'gramophone-action',
      type: 'button',
      title: 'Gramophone',
      icon: '/images/demos/action-3-128x128.png',
    },
    {
      action: 'atom-action',
      type: 'button',
      title: 'Atom',
      icon: '/images/demos/action-4-128x128.png',
    },
  ],
};

registration.showNotification(title, options);

对于每个操作,您可以定义 titleaction(本质上是一个 ID)、icontype。您可以在通知中看到标题和图标。该 ID 将在检测操作按钮被点击情况时使用(将在下一部分详细介绍)。可以省略类型,因为 'button' 是默认值。

在撰写本文时,仅针对 Chrome 和 Opera for Android 支持操作。

上面的示例中定义了四个操作,以说明您可以定义比显示的更多操作数。如果您想知道浏览器将显示的操作数量,可以检查 window.Notification?.maxActions

const maxVisibleActions = window.Notification?.maxActions;

if (maxVisibleActions) {
  options.body = `Up to ${maxVisibleActions} notification actions can be displayed.`;
} else {
  options.body = 'Notification actions are not supported.';
}

在桌面设备上,操作按钮图标会显示各自的颜色(请参阅粉色甜甜圈):

Linux 上包含操作按钮的通知。

在 Android 6 及更低版本中,图标的颜色与系统配色方案相符:

Android 版 Chrome 上带有操作按钮的通知。

在 Android 7 及更高版本中,完全不显示操作图标。

Chrome 有望更改它在桌面设备上的行为,以便与 Android 保持一致(即,应用适当的配色方案,使图标与系统的外观和风格保持一致)。在此期间,您可以将图标的颜色设为 #333333,以匹配 Chrome 的文本颜色。

另外值得一提的是,图标在 Android 上看起来很清晰,但在桌面设备上看起来

我能够在桌面版 Chrome 上使用的最佳尺寸为 24px x 24px。可惜的是,这在 Android 上显得格格不入。

根据这些差异,我们可以采用的最佳实践如下:

  • 坚持使用一致的图标配色方案,至少确保所有图标都能始终向用户显示。
  • 请确保它们在单色模式下显示,因为某些平台可能会以这种方式显示它们。
  • 不妨测试一下大小,看看哪种方法适合您。对我来说,128px × 128px 在 Android 设备上可以正常显示,但在桌面设备上的质量不佳。
  • 您的操作图标应该不会显示。

通知规范正在探索一种定义多种大小的图标的方法,但似乎需要一段时间才能达成一致。

操作(内嵌回复)

您可以通过定义一个 'text' 类型的操作,向通知中添加内嵌回复:

const title = 'Alexey Rodionov';

const options = {
  body: 'How are you doing? )',
  image: '/images/demos/avatar-512x512.jpg',
  icon: '/images/demos/icon-512x512.png',
  badge: '/images/demos/badge-128x128.png',
  actions: [
    {
      action: 'reply',
      type: 'text',
      title: 'Reply',
      icon: '/images/demos/action-5-128x128.png',
    }
  ],
};

registration.showNotification(title, options);

在 Android 设备上的显示效果如下:

Android 上带有回复操作按钮的通知。

点击操作按钮会打开一个文本输入字段:

Android 上的通知,其中包含已打开的文本输入字段。

您可以为文本输入字段自定义占位符:

const title = 'Alexey Rodionov';

const options = {
  body: 'How are you doing? )',
  icon: '/images/demos/avatar-512x512.jpg',
  badge: '/images/demos/badge-128x128.png',
  actions: [
    {
      action: 'reply',
      type: 'text',
      title: 'Reply',
      icon: '/images/demos/action-5-128x128.png',
      placeholder: 'Type text here',
    }
  ],
};

registration.showNotification(title, options);

Android 上的通知,为文本输入字段使用自定义占位符。

在 Windows 版 Chrome 中,文本输入字段始终可见,无需点击操作按钮:

Windows 上的通知,带有文本输入字段和回复操作按钮。

您可以添加多个内嵌回复,也可以合并按钮和内嵌回复:

const title = 'Poll';

const options = {
  body: 'Do you like this photo?',
  image: '/images/demos/cat-image.jpg',
  icon: '/images/demos/icon-512x512.png',
  badge: '/images/demos/badge-128x128.png',
  actions: [
    {
      action: 'yes',
      type: 'button',
      title: '👍 Yes',
    },
    {
      action: 'no',
      type: 'text',
      title: '👎 No (explain why)',
      placeholder: 'Type your explanation here',
    },
  ],
};

registration.showNotification(title, options);

Windows 上的通知,带有文本输入字段和两个操作按钮。

方向

dir 参数可用于定义文本的显示方向:从右到左或从左到右。

在测试中,似乎方向很大程度上是由文本决定的,而不是此参数。根据规范,这是为了向浏览器建议如何布局操作等选项,但我没有发现任何不同。

可能最好定义一下(如果可以),否则浏览器应根据所提供的文本执行正确的操作。

该参数应设置为 autoltrrtl

Chrome 在 Linux 上使用的从右到左语言如下所示:

Linux 上的 Chrome 中显示从右到左的语言的通知。

在 Firefox 中(将鼠标悬停在图标上时),您会看到以下内容:

Linux 上的 Firefox 中显示从右到左的语言的通知。

振动

通过振动选项,您可以定义一种振动模式,该模式会在显示通知时运行,前提是用户当前的设置允许振动(即设备未处于静音模式)。

振动选项的格式应为一个数字数组,用于表示设备应振动的毫秒数,后跟设备不应振动的毫秒数。

const title = 'Vibrate Notification';

const options = {
  // Star Wars shamelessly taken from the awesome Peter Beverloo
  // https://tests.peter.sh/notification-generator/
  vibrate: [
    500, 110, 500, 110, 450, 110, 200, 110, 170, 40, 450, 110, 200, 110, 170,
    40, 500,
  ],
};

registration.showNotification(title, options);

这只会影响支持振动功能的设备。

声音

通过“Sound”参数,您可以定义收到通知时要播放的声音。

在撰写本文时,还没有任何浏览器支持此选项。

const title = 'Sound Notification';

const options = {
  sound: '/demos/notification-examples/audio/notification-sound.mp3',
};

registration.showNotification(title, options);

时间戳

通过时间戳,您可以告知平台触发系统发送推送通知的事件的发生时间。

timestamp 应该是自世界协调时间 (UTC) 00:00:00(即 UNIX 纪元 1970 年 1 月 1 日)以来的毫秒数。

const title = 'Timestamp Notification';

const options = {
  body: 'Timestamp is set to "01 Jan 2000 00:00:00".',
  timestamp: Date.parse('01 Jan 2000 00:00:00'),
};

registration.showNotification(title, options);

用户体验最佳实践

我遇到过的通知中最大的用户体验问题是通知所显示的信息缺乏特异性。

您应该考虑最初发送推送消息的原因,并确保使用所有通知选项来帮助用户了解他们阅读该通知的原因。

说实话,我们很容易看到例子,并想到“我永远不会犯这种错误”。但落入这种陷阱比您想象的更容易。

需要避免的一些常见误区:

  • 不要将网站放在标题或正文中。浏览器会在通知中包含您的网域,因此请勿重复
  • 利用您掌握的所有信息。如果您因为有人向用户发送了消息而发送推送消息,而不是使用“新消息”标题和“点击此处阅读消息”正文,请使用“小明刚刚发送了新消息”标题,并将通知正文设置为消息的一部分。

浏览器和功能检测

在撰写本文时,Chrome 和 Firefox 在通知功能支持方面存在很大差异。

幸运的是,您可以通过查看 window.Notification 原型来检测对通知功能的支持情况。

假设我们想知道通知是否支持操作按钮,我们会执行以下操作:

if ('actions' in window.Notification?.prototype) {
  // Action buttons are supported.
} else {
  // Action buttons are NOT supported.
}

这样,我们就可以更改向用户显示的通知。

对于其他选项,只需按上述步骤操作,将 'actions' 替换为所需的参数名称。

下一步做什么

Codelab