Использование API уведомлений
Безопасный контекст: Эта функция доступна только в безопасных контекстах (HTTPS), в некоторых или во всех поддерживающих браузерах.
Примечание: Эта функция доступна в Web Workers.
API уведомлений позволяет веб-странице или приложению отправлять уведомления, отображаемые вне страницы на системном уровне; это позволяет веб-приложениям отправлять информацию пользователю, даже если приложение неактивно или находится в фоновом режиме. В этой статье рассматриваются основы использования этого API в ваших собственных приложениях.
Обычно системные уведомления относятся к стандартному механизму уведомлений операционной системы: например, представьте себе, как типичная настольная система или мобильное устройство передают уведомления.
Система уведомлений будет, конечно, различаться в зависимости от платформы и браузера, но это нормально, и API уведомлений написан достаточно обобщенно для совместимости с большинством систем уведомлений.
Примеры
Один из наиболее очевидных вариантов использования веб-уведомлений — веб-приложение для почты или IRC, которому необходимо уведомлять пользователя о получении нового сообщения, даже если пользователь выполняет другие действия с другим приложением. Сейчас существуют многочисленные примеры, такие как Slack.
Мы написали реальный пример — приложение списка дел — чтобы дать больше представления о том, как можно использовать веб-уведомления. Оно хранит данные локально с помощью IndexedDB и уведомляет пользователей о сроках задач с помощью системных уведомлений. Скачать код списка дел или посмотреть приложение в работе.
Запрос разрешения
Прежде чем приложение сможет отправить уведомление, пользователь должен предоставить приложению право на это. Это общее требование, когда API пытается взаимодействовать с чем-то вне веб-страницы — по крайней мере один раз, пользователь должен специально разрешить этому приложению отображать уведомления, тем самым позволяя пользователю управлять тем, какие приложения/сайты могут отображать уведомления.
Из-за злоупотреблений push-уведомлениями в прошлом веб-браузеры и разработчики начали внедрять стратегии для смягчения этой проблемы. Запрашивать разрешение на отображение уведомлений следует только в ответ на действие пользователя (например, нажатие кнопки). Это не только лучшая практика — не следует спамить пользователей уведомлениями, на которые они не согласились — но и в будущем браузеры будут явно запрещать запросы разрешений на уведомления, не инициированные действием пользователя. Например, Firefox уже делает это с версии 72, а Safari уже некоторое время.
Кроме того, в Chrome и Firefox вы не можете запрашивать уведомления вообще, если сайт не находится в защищенном контексте (т. е. HTTPS), и вы больше не можете разрешить запросы разрешений на уведомления из кросс-доменных <iframe>.
Проверка текущего статуса разрешения
Вы можете проверить, есть ли у вас разрешение, проверив значение свойства Notification.permission только для чтения. Оно может иметь одно из трех возможных значений:
Получение разрешения
Если разрешение на отображение уведомлений еще не предоставлено, приложение должно использовать метод 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.
См. также
© 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