Spec-Zone.ru › Web APIs

Использование API уведомлений

Безопасный контекст: Эта функция доступна только в безопасных контекстах (HTTPS), в некоторых или во всех поддерживающих браузерах.

Примечание: Эта функция доступна в Web Workers.

API уведомлений позволяет веб-странице или приложению отправлять уведомления, отображаемые вне страницы на системном уровне; это позволяет веб-приложениям отправлять информацию пользователю, даже если приложение неактивно или находится в фоновом режиме. В этой статье рассматриваются основы использования этого API в ваших собственных приложениях.

Обычно системные уведомления относятся к стандартному механизму уведомлений операционной системы: например, представьте себе, как типичная настольная система или мобильное устройство передают уведомления.

Desktop notification: To do list via mdn.github.io HEY! Your task "Go shopping" is now overdue

Система уведомлений будет, конечно, различаться в зависимости от платформы и браузера, но это нормально, и API уведомлений написан достаточно обобщенно для совместимости с большинством систем уведомлений.

Примеры

Один из наиболее очевидных вариантов использования веб-уведомлений — веб-приложение для почты или IRC, которому необходимо уведомлять пользователя о получении нового сообщения, даже если пользователь выполняет другие действия с другим приложением. Сейчас существуют многочисленные примеры, такие как Slack.

Мы написали реальный пример — приложение списка дел — чтобы дать больше представления о том, как можно использовать веб-уведомления. Оно хранит данные локально с помощью IndexedDB и уведомляет пользователей о сроках задач с помощью системных уведомлений. Скачать код списка дел или посмотреть приложение в работе.

Запрос разрешения

Прежде чем приложение сможет отправить уведомление, пользователь должен предоставить приложению право на это. Это общее требование, когда API пытается взаимодействовать с чем-то вне веб-страницы — по крайней мере один раз, пользователь должен специально разрешить этому приложению отображать уведомления, тем самым позволяя пользователю управлять тем, какие приложения/сайты могут отображать уведомления.

Из-за злоупотреблений push-уведомлениями в прошлом веб-браузеры и разработчики начали внедрять стратегии для смягчения этой проблемы. Запрашивать разрешение на отображение уведомлений следует только в ответ на действие пользователя (например, нажатие кнопки). Это не только лучшая практика — не следует спамить пользователей уведомлениями, на которые они не согласились — но и в будущем браузеры будут явно запрещать запросы разрешений на уведомления, не инициированные действием пользователя. Например, Firefox уже делает это с версии 72, а Safari уже некоторое время.

Кроме того, в Chrome и Firefox вы не можете запрашивать уведомления вообще, если сайт не находится в защищенном контексте (т. е. HTTPS), и вы больше не можете разрешить запросы разрешений на уведомления из кросс-доменных <iframe>.

Проверка текущего статуса разрешения

Вы можете проверить, есть ли у вас разрешение, проверив значение свойства Notification.permission только для чтения. Оно может иметь одно из трех возможных значений:

default

Пользователю еще не было предложено разрешение, поэтому уведомления не будут отображаться.

granted

Пользователь предоставил разрешение на отображение уведомлений, после предварительного запроса.

denied

Пользователь явно отказал в разрешении на отображение уведомлений.

Получение разрешения

Если разрешение на отображение уведомлений еще не предоставлено, приложение должно использовать метод Notification.requestPermission() для запроса этого у пользователя. В самом простом виде мы просто включаем следующее:

Notification.requestPermission().then((result) => {
  console.log(result);
});

Это использует версию метода на основе обещаний. Если вы хотите поддерживать более старые версии, вам, возможно, придется использовать более старую версию с обратным вызовом, которая выглядит так:

Notification.requestPermission((result) => {
  console.log(result);
});

Версия с обратным вызовом необязательно принимает функцию обратного вызова, которая вызывается после того, как пользователь ответил на запрос отображения разрешений.

Примечание: Нет надежного способа определить, поддерживает ли Notification.requestPermission версию на основе обещаний. Если вам необходимо поддерживать более старые браузеры, просто используйте версию с обратным вызовом — хотя она устарела, она по-прежнему работает в новых браузерах. См. таблицу совместимости с браузерами в разделе таблица совместимости.

Пример

В нашем демо-приложении списка дел мы включили кнопку «Включить уведомления», которая при нажатии запрашивает разрешения на уведомления для приложения.

<button id="enable">Enable notifications</button>

Нажатие на неё вызывает функцию askNotificationPermission().

function askNotificationPermission() {
  // Check if the browser supports notifications
  if (!("Notification" in window)) {
    console.log("This browser does not support notifications.");
    return;
  }
  Notification.requestPermission().then((permission) => {
    // set the button to shown or hidden, depending on what the user answers
    notificationBtn.style.display = permission === "granted" ? "none" : "block";
  });
}

В первую очередь, взглянув на второй блок, вы увидите, что мы сначала проверяем, поддерживаются ли уведомления. Если они поддерживаются, мы запускаем версию на основе обещаний Notification.requestPermission(), а если нет, то записываем сообщение в консоль.

Внутри обработчика разрешения обещаний, переданного then, мы показываем или скрываем кнопку в зависимости от того, что выбрал пользователь в диалоговом окне разрешений. Мы не хотим показывать её, если разрешение уже предоставлено, но если пользователь выбрал отказ в разрешении, мы хотим дать ему возможность изменить своё мнение позже.

Создание уведомления

Создание уведомления просто; используйте конструктор Notification. Этот конструктор ожидает заголовок для отображения в уведомлении и некоторые параметры для улучшения уведомления, такие как icon или текстовый body.

Например, в примере списка дел мы используем следующий фрагмент кода для создания уведомления при необходимости (находится внутри функции createNotification()):

const img = "/to-do-notifications/img/icon-128.png";
const text = `HEY! Your task "${title}" is now overdue.`;
const notification = new Notification("To do list", { body: text, icon: img });

Закрытие уведомлений

Используйте close() для удаления уведомления, которое больше не актуально для пользователя (например, пользователь уже прочитал уведомление на веб-странице, в случае приложения для обмена сообщениями или следующая песня уже играет в музыкальном приложении для уведомлений о смене песен). Большинство современных браузеров автоматически закрывают уведомления через несколько секунд (около четырех секунд), но это не то, о чем вам следует беспокоиться, так как это зависит от пользователя и пользовательского агента. Закрытие также может происходить на уровне операционной системы, и пользователи должны контролировать это. В старых версиях Chrome уведомления не удалялись автоматически, поэтому вы можете сделать это после setTimeout() только для этих устаревших версий, чтобы не удалять уведомления из системных треев в других браузерах.

const n = new Notification("My Great Song");
document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "visible") {
    // The tab has become visible so clear the now-stale Notification.
    n.close();
  }
});

Примечание: Этот API не следует использовать только для удаления уведомления со страницы через заданный интервал времени (в современных браузерах), поскольку этот метод также удалит уведомление из любого системного трея, предотвращая взаимодействие с ним после его первоначального показа.

Примечание: При получении события "close" нет гарантии, что уведомление закрыл пользователь. Это соответствует спецификации, которая гласит: «Когда уведомление закрывается, либо основой платформы уведомлений, либо пользователем, должны выполняться шаги закрытия для него».

События уведомлений

На экземпляре Notification срабатывают четыре события:

click

Срабатывает, когда пользователь нажимает на уведомление.

close

Срабатывает при закрытии уведомления.

error

Срабатывает, если что-то идет не так с уведомлением; обычно это происходит потому, что уведомление не удалось отобразить по какой-либо причине.

show

Срабатывает при отображении уведомления пользователю.

Эти события можно отслеживать, используя обработчики onclick, onclose, onerror и onshow. Поскольку Notification также наследуется от EventTarget, на нём можно использовать метод addEventListener().

Замена существующих уведомлений

Обычно нежелательно, чтобы пользователь получал много уведомлений за короткий промежуток времени — например, что произойдёт, если приложение для обмена сообщениями будет уведомлять пользователя о каждом входящем сообщении, и им отправляется много сообщений? Чтобы избежать спама уведомлениями, можно изменить очередь ожидающих уведомлений, заменив одно или несколько ожидающих уведомлений новым.

Для этого можно добавить тег к любому новому уведомлению. Если уведомление с таким же тегом уже есть, но ещё не отображено, новое уведомление заменит предыдущее. Если уведомление с таким же тегом уже отображается, предыдущее уведомление закрывается, а новое отображается.

Пример с тегом

Предположим следующий базовый HTML:

<button id="notify">Notify me!</button>
<section id="demo-logs"></section>

Можно обрабатывать несколько уведомлений таким образом:

const demoLogs = document.querySelector("#demo-logs");

window.addEventListener("load", () => {
  const button = document.querySelector("#notify");

  button.addEventListener("click", () => {
    if (Notification?.permission === "granted") {
      demoLogs.innerText += `The site has permission to show notifications. Showing notifications.\n`;
      // If the user agreed to get notified
      // Let's try to send ten notifications
      let i = 0;
      // Using an interval cause some browsers (including Firefox) are blocking notifications if there are too much in a certain time.
      const interval = setInterval(() => {
        // Thanks to the tag, we should only see the "Hi no 9 from MDN." notification
        const n = new Notification(`Hi no ${i} from MDN.`, {
          tag: "soManyNotification",
        });
        if (i === 9) {
          clearInterval(interval);
        }
        i++;
      }, 200);
    } else if (Notification?.permission !== "denied") {
      demoLogs.innerText += "Requesting notification permission.\n";
      // If the user hasn't told if they want to be notified or not
      // Note: because of Chrome, we are not sure the permission property
      // is set, therefore it's unsafe to check for the "default" value.
      Notification.requestPermission().then((status) => {
        // If the user said okay
        if (status === "granted") {
          demoLogs.innerText +=
            "User granted the permission. Sending notifications.\n";
          let i = 0;
          // Using an interval cause some browsers (including Firefox) are blocking notifications if there are too much in a certain time.
          const interval = setInterval(() => {
            // Thanks to the tag, we should only see the "Message no 9 from MDN." notification
            const n = new Notification(`Message no ${i} from MDN.`, {
              tag: "soManyNotification",
            });
            if (i === 9) {
              clearInterval(interval);
            }
            i++;
          }, 200);
        } else {
          // Otherwise, we can fallback to a regular modal alert
          demoLogs.innerText += `User denied the permission request.\n`;
        }
      });
    } else {
      // If the user refuses to get notified, we can fallback to a regular modal alert
      demoLogs.innerText += `The site does not have permission to show notifications.\n`;
    }
  });
});

Результат

Для тестирования приведенного выше примера измените настройку отправки уведомления для сайта https://live.mdnplay.dev.

См. также

  • Notification

© 2005–2024 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/API/Notifications_API/Using_the_Notifications_API

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API