Задача коммуникации между вкладками и выявления активной вкладки

Наглядный пример задачи — сайт vk.com. Каждый раз когда вы воспроизводите музыку или видео в одной вкладке — в других вкладках воспроизведение останавливается. И если вы обратитесь в интернет за помощью в решении данной задачи, то наверняка найдете описание Storage Events или Page Visibility API или даже готовые решения, к примеру Visibility.js.На хабре уже был обзор этих вещей, к примеру вот и ещё.

14ffed119e084ee1a6ef12c0b6225b95.jpg

Я прошел по этому пути, но не одно из решений меня не устроило. Мне хотелось чего-нибудь простого, легковесного и не требующего глубокого изучения деталей.Решение, которое получилось в итоге, обрело название DuelJS (просто рандомное уникальное название) и ниже я попробую сравнить его с Visibility.js, дабы избежать лишней критики в свою сторону.

Активная вкладкаУдобная кроссбраузерная обертка для простого отражения состояния «эта вкладка сейчас активна», в visibility.js будет выглядеть следующим образом: if ('visible' == Visibility.state ()) { // эта вкладка активна } У вкладки Visibility есть 3 состояния: visible, hidden и prerender.Преимуществом Visibility также являются callbacks, которые вы можете вешать на множество событий, таких как активизация вкладки, setInterval в активном окне и тому подобное.

Философия DuelJS слегка упрощена:1. Все вкладки имеют лишь 2 состояния — Master и Slave2. Мастер вкладка это вкладка в которой ведется работа — ничего лишнего, все остальные есть Slave.

При таком подходе достаточно лишь одной функции: window.isMaster () — проверить является ли вкладка мастером.

if (window.isMaster ()) { // эта вкладка активна } Коммуникации между вкладками Теперь перейдем к коммуникациям между вкладками. Наиболее подходящим решением мне показалось использование Storage Events, хотя они и не без проблем. К слову находил я в гугле еще такие варианты как использование postMessage API или WebSockets.Основная проблема Storage Events заключается в их плохой поддержке некоторыми MSIE, хотя до недавнего времени и у других браузеров тоже могли возникать с этим проблемы.

Так как Visibility.js является по сути оберткой над Page Visibility API — работа со Storage Events в ней отсутствует.

В DuejJS существует кроссбраузерная обертка над Storage Events, которая выражается в следующей философии:1. Коммуникации между вкладками осуществляются при помощи каналов2. Внутри канала вкладки могут запускать события, на которые могут реагировать другие вкладки в этом канале

Создать канал достаточно просто:

var ch = duel.channel ('channel_name'); // channel_name — имя канала Теперь определим поведение при вызове события qwerty: ch.on ('qwerty', function (a, b, c, …) {}) Метод on у канала определяет его поведение. В функции, передаваемой вторым параметром может быть сколько угодно аргументов, или не быть вовсе.Запустить событие так же легко. Слово on теперь заменим на broadcast, а передаваемые аргументы вставим после названия события:

ch.broadcast ('qwerty', a, b, c, …) Создание плеера с поведением как на vk.com Для нетерпеливых читателей сразу даю ссылку на рабочий пример.Основная суть приложения заключается в трех строках:1. var player = duel.channel ('player'); (определение канала)2. player.on ('stop', function () {… (определение поведения при событии stop)3. player.broadcast ('stop'); (запуск события stop)

Полный код страницы выглядит следующим образом: Остановлено

PLAY
Открыть новую вкладку Заключение Буду очень рад если вам поможет данное решение и вы используете его в своих проектах. Я открыт к идеям по улучшению. Либа — кроссбраузерная и работает в том числе и в IE, за счет встроенных хаков.6717569a96814cfc9d70d60c62046858.jpg

Полезные ссылки Краткая документация DuelJS на сайтеРепозиторий DuelJS на GitHubЕщё одна демка DuelJS

© Habrahabr.ru