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

    Greetings.

    I think many people who have a VKontakte account and listen to music there have noticed that if you turn on the track on one tab and then turn on the second on the other, the first track will pause. Roughly the same thing happens with various notifications (new message, reply to comment / post, etc.) - it is displayed only in the active tab. Who cares how this works and how to do something like this on your site, you are welcome for the 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 identifier and player status are saved (for example, 'play'). If another track is launched in another window (of the same domain, of course), all tabs pause their players. Etc.

    Practice


    We will store the event data in one key, for example, 'notifier_event'. We will write there a string representation of a certain 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. The event time must be specified so that the event of changing the key value is always processed.

    When an event is received, we simply start the necessary handler and perform all the 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 seen here - track 1 , track 2 .

    Source code


    Sources can be downloaded from the GitHub repository .

    The audio recorded in the demo is distributed under the Attribution-ShareAlike License .

    Also popular now: