Введение в механизм Веб-оповещений
Время соединений на скорости 56k уже стерлось из людской памяти (первыми не выдержали пользователи мобильных устройств). Это было время, когда браузеры могли открывать только одну вкладку в окне, и никто даже и представить себе не мог просмотр сайтов в нескольких вкладках. Сегодня на нас свалились все эти социальные сети, посты, ответы, комментарии, фотографии, видео, и много чего еще. Было создано несколько систем, которые пришли на смену необходимости проверять каждую вкладку на предмет новой активности. Одним из таких способов явилась система оповещений, которые широко распространены на различных сайтах.
До недавнего времени разработчикам приходилось изобретать свои собственные системы оповещений, что вылилось в огромное количество разнообразных решений. Консорциум W3C разработал стандарт для API, чтобы решить эту проблему – стандарт под названием API Веб-оповещений.
Мы уже знакомы с подобной концепцией на мобильных устройствах. Попробуйте просто выйти из онлайна на пару часов, и при подключении к интернету на вас свалится тонна оповещений от различных приложений. Было бы здорово иметь подобный механизм и на наших сайтах, который бы работал одинаково на десктопных и мобильных системах. Как уже было сказано в данном введении, такая система была разработана и стандартизована, так что теперь у нас есть API Веб-оповещений.
Что такое API веб-оповещений?
Определение API веб-оповещений гласит, что это “API для оповещения конечного пользователя. Оповещение позволяет предупредить пользователя вне контекста веб-страницы о том, что на странице произошло какое-то событие – например, пришло новое письмо. Так как в разных браузерах используются свои стили, а также в зависимости от устройств, которые мы используем, оповещения будут отображены в различных местах (например, на мобильном устройстве оповещения могут приходить на панель оповещений). Стоит отметить, что перед тем, как пользователю будет отображено оповещение, он должен дать свое согласие на отображения оповещений от вашего сайта.
Пример оповещения через механизм оповещения браузера Firefox
Это API существует уже довольно продолжительное время, да так, что спецификации менялись уже несколько раз. У данной спецификации есть две мажорные версии. Первая версия была имплементирована в старых версиях браузеров Chrome и Firefox. На данный момент спецификация, вроде, стабильна, хотя на момент 19 апреля 2014 она все еще остается черновиком W3C.
Нетрудно представить себе случаи, где было бы полезно воспользоваться этим API. например, вы бы хотели получить оповещение сразу же, как вам бы пришло новое письмо. Также вы бы хотели узнать о том, что кто-то упомянул вас в своем твите, или кто-то запостил фото с вами на Facebook или Google+.
Теперь, когда мы поняли, для чего нужен этот API, и в чем его прелести, давайте углубимся в описание методов, свойств и событий.
Методы, свойства и события
Доступ к механизму веб-оповещений осуществляется через свойство Notification
объекта window
. Это конструктор, который позволяет создать экземпляр оповещения. Он принимает два параметра – строку с заголовком оповещения, и опциональный объект с настройками. Перед тем, как создать экземпляр оповещения, давайте взглянем на те настройки, которые мы можем указать:
body
: строка, использующаяся для указания цели уведомленияlang
: указывает язык оповещения. Значение должно быть совместимо со стандартом BCP 47. Примеры валидного значения:en-US
иit-IT
dir
: указывает направление текста сообщения. Значение может бытьauto
, что подразумевает, что направление текста будет определяться браузером,ltr
указывает, что текст будет идти слева направо (для европейских языков), илиrtl
- текст справа налево (для некоторых азиатских языков)tag
: строка, использующаяся как идентификатор, которая служит для получения, замещения или удаления оповещения.icon
: указывает URL изображения, которое будет использовано в качестве иконки оповещения
Чтобы создать экземпляр объекта Notification
, необходимо использовать подобное выражение:
1 2 3 |
var notification = new Notification('Получено письмо', { body: 'У вас всего 3 непрочитанных письма' }); |
Совсем несложно, не так ли?
Настройки, которые мы только что разбирали, также доступны как свойства для чтения у экземпляра оповещения. В дополнение к ним, объект Notification
также предоставляет свойство permission
, которое содержит строку, представляющее текущее разрешение на отображение оповещений. Его значение может быть одним из следующих:
denied
- пользователь запретил отображение оповещенийgranted
- пользователь разрешил отображение оповещенийdefault
- выбор пользователя неизвестен
API предоставляет два метода: requestPermission()
и close()
. Как можно догадаться из названия, первый служит для запроса прав на отображение оповещений у пользователя, а второй программно закрывает оповещение. requestPermission()
является методом объекта Notification
, и опционально принимает функцию обратного вызова, которая выполняется, когда пользователь принимает или отклоняет разрешение. Выбор пользователя передается в функцию обратного вызова параметром, который может принимать значения granted
, denied
или default
. close()
- метод экземпляра, и не принимает параметров.
Иногда необходимо выполнить какое-то действие, как только меняется состояние оповещения. Например, мы хотим знать, если пользователь кликнул по оповещению, или же оно было закрыто. Для того, чтобы это сделать, можно навесить обработчик на одно из четырех возможных событий:
onclick
- выбрасывается, когда пользователь кликает по оповещениюonclose
- выбрасывается, когда пользователь или браузер закрывают оповещениеonerror
- выбрасывается, если с оповещением случилась ошибкаonshow
- выбрасывается при отображении оповещения
Простейший пример использования событий показан ниже.
1 2 3 4 5 6 7 |
var notification = new Notification('Получено письмо', { body: 'У вас всего 3 непрочитанных письма' }); notification.onshow = function() { console.log('Отображено оповещение'); }; |
Совместимость с браузерами
Поддержка механизма оповещений не очень хороша как на десктопных системах, так и на мобильных. На десктопных системах Chrome и Firefox уже давно внедрили первую версию API. Но если рассматривать поддержку только новой версии стандарта, то ее поддержка начинается в версиях Chrome 22 и Firefox 22 (обе без вендорных префиксов). Safari 6+ также поддерживает механизм оповещений. на мобильных системах только Firefox и Blackberry поддерживают механизм оповещений полностью. Проверка того, поддерживает или нет браузер оповещения сводится к написанию следующего кода:
1 2 3 4 5 |
if ('Notification' in window) { // API поддерживается } else { // API не поддерживается } |
Демонстрация
В этом разделе я покажу небольшую демонстрацию, чтобы дать вам представление, как работает этот механизм на практике. Демонстрация состоит из двух частей. В первой части представлена форма которая позволяет собственноручно написать произвольный текст, который будет использован для показа оповещения. Во второй части будет кнопка, которая позволит быстро просмотреть, что делает данный механизм, используя предопределенные параметры, которые я включил в демонстрацию. Оба этих запроса попросят разрешения у пользователя. Как только разрешения будут даны, появится оповещение на экране (в случае десктопного браузера), или в панели уведомлений (в случае с мобильным устройством).
В части, где описаны скрипты, первым, что мы делаем – проверяем, поддерживает ли браузер механизм оповещений. Если API не поддерживается, мы отображаем сообщение “API не поддерживается”, и отключаем обе кнопки, которые отсылают уведомления. Если API поддерживается, мы вешаем обработчик события click по кнопкам. Как можно видеть из нижеприведенного кода, обработчик тот же, только в нем показываются различные заголовки и сообщения, в зависимости от того, какая кнопка была нажата:
1 2 3 4 5 |
if (event.target.id === 'button-wn-show-preset') { // Используем параметр из настроек } else { // Используем свои параметры } |
В дополнение к отображению оповещений, мы навесим обработчик на каждое из четырех событий, выбрасываемых экземпляром оповещения. Обработчик будет только логировать имя выброшенного события и кнопки, которая его вызвала, в отдельный элемент textform
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Демонстрация API веб-оповещений</title> <style> * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } body { max-width: 500px; margin: 2em auto; padding: 0 0.5em; font-size: 20px; } h1 { text-align: center; } .hidden { display: none; } #custom-notification { margin-top: 1em; } label { display: block; } input[name="title"], textarea { width: 100%; } input[name="title"] { height: 2em; } textarea { height: 5em; } .buttons-wrapper { text-align: center; } .button-demo { padding: 0.5em; margin: 1em; } #log { height: 200px; width: 100%; overflow-y: scroll; border: 1px solid #333333; line-height: 1.3em; } .author { display: block; margin-top: 1em; } </style> </head> <body> <h1>Web Notifications API</h1> <span id="wn-unsupported" class="hidden">API не поддерживается</span> <form id="custom-notification" action=""> <label for="title">Заголовок:</label> <input type="text" id="title" name="title" /> <label for="body">Тело:</label> <textarea id="body" name="body"></textarea> <div class="buttons-wrapper"> <button id="button-wn-show-preset" class="button-demo">Показать оповещение по предопределенным настройкам</button> <input type="submit" id="button-wn-show-custom" class="button-demo" value="Показать свое оповещение" /> </div> </form> <h3>Log</h3> <div id="log"></div> <button id="clear-log" class="button-demo">Очистить лог</button> <script> if (!('Notification' in window)) { document.getElementById('wn-unsupported').classList.remove('hidden'); document.getElementById('button-wn-show-preset').setAttribute('disabled', 'disabled'); document.getElementById('button-wn-show-custom').setAttribute('disabled', 'disabled'); } else { var log = document.getElementById('log'); var notificationEvents = ['onclick', 'onshow', 'onerror', 'onclose']; function notifyUser(event) { var title; var options; event.preventDefault(); if (event.target.id === 'button-wn-show-preset') { title = 'Получено письмо'; options = { body: 'У вас 3 непрочитанных сообщения', tag: 'preset', icon: 'http://www.audero.it/favicon.ico' }; } else { title = document.getElementById('title').value; options = { body: document.getElementById('body').value, tag: 'custom' }; } Notification.requestPermission(function() { var notification = new Notification(title, options); notificationEvents.forEach(function(eventName) { notification[eventName] = function(event) { log.innerHTML = 'Событие "' + event.type + '" выброшено для оповещения "' + notification.tag + '"<br />' + log.innerHTML; }; }); }); } document.getElementById('button-wn-show-preset').addEventListener('click', notifyUser); document.getElementById('button-wn-show-custom').addEventListener('click', notifyUser); document.getElementById('clear-log').addEventListener('click', function() { log.innerHTML = ''; }); } </script> </body> </html> |
Заключение
В этой статье мы рассмотрели механизм веб-оповещений и возможные места его использования. Также мы описали методы, свойства и события, предоставляемые API. Как видно, использовать API очень просто, так что вам будет несложно внедрить его на следующем вашем проекте.
К сожалению, его поддержка браузерами оставляет желать лучшего, но, так как Firefox, Chrome и Safari уже внедрили его, то и остальные браузеры должны подтянуться. Чтобы проникнуться концепцией оповещений, не забудьте поиграться с демкой, и возможно, попробовать самому изменить код.
Перевод: Станислав Протасевич