📜 ⬆️ ⬇️

The system of notifications about events on the site (for example, audio player VKontakte)

Greetings.

I think many who have a Vkontakte account and listen to music there, noticed that if you turn on a track on one tab and then turn on the second one, the first track will pause. Approximately the same thing happens with different notifications (new message, reply to comment / post, etc.) - it is displayed only in the active tab. Who cares how it works and how to do this on your site, you are welcome for a habrakat.

Theory


And all this is implemented using HTML5 Local Storage . Take the same audio player. When you start a track in Local Storage, the window ID and player status (for example, 'play') is saved. If another track is launched in another window (of the same domain, of course), all tabs pause their players. And so on.

Practice


We will store the event data in one key, for example, 'notifier_event'. We will write there a string representation of some object of the following form:
var evt = { 'notifier_id': 'aAr63gd2', 'event': 'audiostate', 'event_data': {'state': 'play'}, 'event_ts': Math.round(new Date().getTime() / 1000) }; 

The notifier_id field is the ID of the tab from which the event was sent; 'event' is the name of the event, 'event_data' is the event data, respectively, 'event_ts' is the Unix Timestamp. Event time must be specified so that the key value change event is always processed.
')
When an event is received, simply launch the necessary handler and perform all actions that relate to the received event. That's all :)

Listings


Event handling
 /** * 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(); } } }; 


Demo


An example can be found here - track 1 , track 2 .

Sources


Sources can be downloaded from the GitHub repository.

Presented in the demo audio distributed under the license Attribution-ShareAlike License .

Source: https://habr.com/ru/post/153937/


All Articles