显示通知

通知选项分为两个部分,一部分处理视觉方面(本节),另一部分解释通知的行为方面(下一节)。

您可以使用 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>",
}

让我们看看视觉选项

Dissection of the UI of a Notification.

标题和正文选项

这是在 Windows 上的 Chrome 中没有标题和选项的通知的样子

Notification without the title and options in Chrome on Windows.

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

如果渐进式 Web 应用安装在设备上,则将使用 Web 应用名称而不是浏览器名称

Notification with the web app name instead of the browser name.

如果我们运行以下代码

const title = 'Simple Title';

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

registration.showNotification(title, options);

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

Notification with title and body text in Chrome on Linux.

在 Linux 上的 Firefox 中,它看起来像这样

Notification with title and body text in Firefox on Linux.

这是在 Linux 上的 Chrome 中标题和正文中包含大量文本的通知的样子

Notification with long title and body text in Chrome on Linux.

Linux 上的 Firefox 折叠了正文文本,直到您将鼠标悬停在通知上,导致通知展开

Notification with long title and body text in Firefox on Linux.

Notification with long title and body text in Firefox on Linux while hovering over the notification with the mouse cursor.

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

Notification with title and body text in Firefox on Windows.

Notification with long title and body text in Firefox on Windows.

如您所见,相同的通知在不同的浏览器中可能看起来不同。在不同平台上的同一浏览器中,它也可能看起来不同。

Chrome 和 Firefox 在提供系统通知和通知中心的平台上使用它们。

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

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

图标

icon 选项本质上是一个小图像,您可以将其显示在标题和正文文本旁边。

在您的代码中,您需要提供您要加载的图像的 URL

const title = 'Icon Notification';

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

registration.showNotification(title, options);

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

Notification with icon in Chrome on Linux.

以及 Linux 上的 Firefox 中的通知

Notification with icon in Firefox on Linux.

遗憾的是,对于图标使用什么尺寸的图像没有任何明确的指南。

Android 似乎需要 64dp 的图像(即 64px 乘以设备像素比)。

假设设备的最高像素比为 3,则 192px 或更大的图标尺寸是安全的选择。

徽章

badge 是一个小型的单色图标,用于向用户描绘有关通知来源的更多信息

const title = 'Badge Notification';

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

registration.showNotification(title, options);

在撰写本文时,徽章仅在 Android 上的 Chrome 中使用。

Notification with badge in Chrome on Android.

在其他浏览器(或没有徽章的 Chrome)上,您会看到浏览器的图标。

Notification with badge in Firefox on Android.

icon 选项一样,对于使用什么尺寸也没有真正的指南。

查阅 Android 指南,建议尺寸为 24px 乘以设备像素比。

这意味着 72px 或更大的图像应该是不错的选择(假设最大设备像素比为 3)。

图像

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

const title = 'Image Notification';

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

registration.showNotification(title, options);

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

Notification with image in Chrome on Linux.

在 Android 上的 Chrome 中,裁剪和比例有所不同

Notification with image in Chrome on Android.

鉴于桌面和移动设备之间的比例差异,很难提出指南。

由于桌面上的 Chrome 不会填充可用空间且比例为 4:3,因此最好的方法可能是提供此比例的图像,并允许 Android 裁剪图像。话虽如此,image 选项可能仍会更改。

在 Android 上,唯一的 指南 是宽度为 450dp。

使用此指南,宽度为 1350px 或更大的图像将是一个不错的选择。

操作(按钮)

您可以定义 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' 是默认值。

在撰写本文时,只有 Android 版 Chrome 和 Opera 支持操作。

在上面的示例中,定义了四个操作来说明您可以定义比将显示的更多操作。如果您想知道浏览器将显示的操作数,可以查看 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.';
}

在桌面上,操作按钮图标显示其颜色(请参见粉红色的甜甜圈)

Notification with action buttons on Chrome on Linux.

在 Android 6 及更早版本上,图标会着色以匹配系统配色方案

Notification with action buttons on Chrome for Android.

在 Android 7 及更高版本上,操作图标根本不显示。

Chrome 希望更改其在桌面上的行为以匹配 Android(即,应用适当的配色方案以使图标与系统外观和感觉相匹配)。同时,您可以通过使图标的颜色为 #333333 来匹配 Chrome 的文本颜色。

还值得指出的是,图标在 Android 上看起来很清晰,但在桌面上清晰。

我可以在桌面 Chrome 上使用的最佳尺寸是 24px x 24px。但这在 Android 上看起来很突兀。

我们可以从这些差异中得出的最佳实践

  • 为您的图标坚持一致的配色方案,以便至少您的所有图标都一致地显示给用户。
  • 确保它们在单色中也能正常工作,因为某些平台可能会以这种方式显示它们。
  • 测试尺寸并查看什么对您有效。128px × 128px 在 Android 上对我来说效果很好,但在桌面上质量很差。
  • 预计您的操作图标根本不会显示。

Notification 规范正在探索一种定义多种尺寸图标的方法,但看起来在达成一致之前还需要一段时间。

操作(内联回复)

您可以通过定义类型为 '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 上的样子

Notification on Android with a reply action button.

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

Notification on Android with an opened text input field.

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

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);

Notification on Android with customized placeholder for text input field.

在 Windows 上的 Chrome 中,文本输入字段始终可见,无需单击操作按钮

Notification on Windows with a text input field and a reply action button.

您可以添加多个内联回复或组合按钮和内联回复

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);

Notification on Windows with a text input field and two action buttons.

方向

dir 参数允许您定义文本应显示的哪个方向,从右到左或从左到右。

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

如果可以,最好定义,否则浏览器应该根据提供的文本做正确的事情。

该参数应设置为 autoltrrtl

在 Linux 上的 Chrome 上使用的从右到左的语言看起来像这样

Notification with right-to-left language on Chrome on Linux.

在 Firefox 中(悬停在它上面时),您会得到这个

Notification with right-to-left language on Firefox on Linux.

震动

vibrate 选项允许您定义在显示通知时运行的振动模式,假设用户当前设置允许振动(即设备未处于静音模式)。

vibrate 选项的格式应为数字数组,描述设备应振动的毫秒数,后跟设备应振动的毫秒数。

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 应该是自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数(即 UNIX 纪元)。

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);

用户体验最佳实践

我见过的通知的最大用户体验失败是通知显示的信息缺乏特异性。

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

老实说,很容易看到一些例子,并认为“我永远不会犯那个错误”。但陷入陷阱比您想象的要容易。

一些常见的陷阱要避免

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

浏览器和功能检测

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

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

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

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

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

对于其他选项,只需执行与上述相同的操作,将 'actions' 替换为所需的参数名称即可。

下一步去哪里

代码实验室