Приветствую.
Думаю, многие, кто имеет аккаунт ВКонтакте и слушает там музыку, замечали, что если на одной вкладке включить трек, а затем уже на другой включить второй, первый трек уйдет в паузу. Примерно то же самое происходит с различными уведомлениями (новое сообщение, ответ на комментарий/запись и т.д.) — отображается оно только в активной вкладке. Кому интересно как это работет и каким образом сделать подобное у себя на сайте, милости просим за хабракат.
А реализуется всё это с помощью HTML5 Local Storage. Возьмем тот же аудиопроигрыватель. При запуске трека в Local Storage сохраняется идентификатор окна и состояние проигрывателя (к примеру, 'play'). Если в другом окне (одного и того же домена, разумеется) запускается ещё один трек, все вкладки ставят свои проигрыватели на паузу. И так далее.
Хранить данные события будем в одном ключе, к примеру, 'notifier_event'. Писать туда будем строковое представление некоего объекта следующего вида:
Поле notifier_id — это ID вкладки, из которой было послано событие; 'event' — название события, 'event_data' — соответственно данные события, 'event_ts' — Unix Timestamp. Время ивента нужно указывать чтобы событие смены значения ключа отрабатывалось всегда.
При получении события просто запускаем необходимый обработчик и выполняем все действия, которые относятся к полученному событию. Вот и всё :)
Обработка события
Пример можно посмотреть здесь — трек 1, трек 2.
Исходники можно скачать из репозитория GitHub.
Представленные в демо аудиозаписи распространяются под лицензией Attribution-ShareAlike License.
Думаю, многие, кто имеет аккаунт ВКонтакте и слушает там музыку, замечали, что если на одной вкладке включить трек, а затем уже на другой включить второй, первый трек уйдет в паузу. Примерно то же самое происходит с различными уведомлениями (новое сообщение, ответ на комментарий/запись и т.д.) — отображается оно только в активной вкладке. Кому интересно как это работет и каким образом сделать подобное у себя на сайте, милости просим за хабракат.
Теория
А реализуется всё это с помощью HTML5 Local Storage. Возьмем тот же аудиопроигрыватель. При запуске трека в Local Storage сохраняется идентификатор окна и состояние проигрывателя (к примеру, 'play'). Если в другом окне (одного и того же домена, разумеется) запускается ещё один трек, все вкладки ставят свои проигрыватели на паузу. И так далее.
Практика
Хранить данные события будем в одном ключе, к примеру, 'notifier_event'. Писать туда будем строковое представление некоего объекта следующего вида:
var evt = { 'notifier_id': 'aAr63gd2', 'event': 'audiostate', 'event_data': {'state': 'play'}, 'event_ts': Math.round(new Date().getTime() / 1000) };
Поле notifier_id — это ID вкладки, из которой было послано событие; 'event' — название события, 'event_data' — соответственно данные события, 'event_ts' — Unix Timestamp. Время ивента нужно указывать чтобы событие смены значения ключа отрабатывалось всегда.
При получении события просто запускаем необходимый обработчик и выполняем все действия, которые относятся к полученному событию. Вот и всё :)
Листинги
Обработка события
/** * Binds storage key change event * @return void **/ Notifier.prototype.bindEvent = function() { if (!this.isAvailable()) return false; var t = this; $(window).bind('storage', function(e) { var evt = e.originalEvent; if (evt.key == t.m_localStorageKey) // Если измененный ключ - ключ хранения события, вызываем обработчика t.handleLsEvent(JSON.parse(evt.newValue)); }); }; /** * Handles changes for certain localStorage event * @param Object evt **/ Notifier.prototype.handleLsEvent = function(evt) { switch (evt.event) { case 'audiostate': this.handleAudioStateEvent(evt); // Обработчик нажатия кнопки play/pause проигрывателя break; } }; /** * Handles audiostate event * @param Object evt * @return void **/ Notifier.prototype.handleAudioStateEvent = function(evt) { if (evt.notifier_id != this.getNotifierId()) { if (evt.event_data.state == 'play') { // Если какая-то вкладка начала проигрывание трека, ставим текущий проигрыватель на паузу player.pause(); } } };
Демо
Пример можно посмотреть здесь — трек 1, трек 2.
Исходники
Исходники можно скачать из репозитория GitHub.
Представленные в демо аудиозаписи распространяются под лицензией Attribution-ShareAlike License.
