V lednu tohoto roku jQuery oznámila novou registr pluginů , takže se mi zdálo, že je skvělý čas napsat návod, který kombinuje budování pluginu jQuery s mou vášní - webových technologií v reálném čase.

Webové technologie v reálném čase umožňují skutečně snadné přidání živého obsahu do dříve statických webových stránek. Živý obsah může přinést stránku naživu, uchovat uživatele a odstranit potřebu pravidelného obnovování stránky. Aktualizace v reálném čase se obecně dosahují připojením ke zdroji dat, přihlašováním se k údajům, které chcete přidat na stránku, a následným aktualizováním stránky při příchodu dat. Proč to však nelze dosáhnout jednoduchým označením stránky za účelem zjištění, jaké údaje by měly být zobrazeny a kde? No, možná to může!

jQuery je tagline je napsat méně, dělat víc . Titulek pluginu jQuery Realtime, který budeme vytvářet v tomto tutoriálu, bude méně psaný, a to v reálném čase.

V tomto tutoriálu vytvoříme plugin jQuery, díky němuž je snadné přidávat do reálného obsahu na stránku jednoduchým přidáním nějaké značky. Nejprve se budeme zabývat tím, jak používat službu nazvanou Posunovač k odběru dat v reálném čase. Pak definujeme způsob označování dokumentu HTML5 s atributy 'data- *' takovým způsobem, který může být dotazován naším pluginem v reálném čase jQuery a převeden na předplatné dat v reálném čase. Nakonec vytvoříme plugin jQuery, který použije atributy pro přihlášení k datům a okamžitě zobrazí aktualizace v rámci stránky.

Pokud se chcete jen potápět přímo ve vás Zobrazit demo v akci nebo můžete stáhněte kód a začít hackovat.

Základy ovládání

Pusher je hostovaná služba, která usnadňuje přidávání obsahu v reálném čase a interaktivních zážitků do webových a mobilních aplikací. Zde se budeme jednoduše připojovat, přihlásit se k odběru některých dat a pak aktualizovat stránku, když data přicházejí.

Chcete-li to prokázat, vytvořte soubor s názvem "example.html" a v knihovně JavaScript Pusher z CDN Pushmanu. Víme, že budeme používat jQuery 2.0.0, takže bychom to měli také zahrnout nyní:

Creating a realtime jQuery plugin | Webdesigner Depot

Připojit

Po přidání knihovny JavaScript Pusher se můžeme připojit k zařízení Pusher tak, že vytvoříme novou instanci "Pusher" a předáme aplikační klíč. Vytvořte další "

Note: For the tutorial we’ll use an application key that I’ve provided but for your own applications you’ll need to sign up to Pusher to get your own.

You can check that you’re connected in three different ways. You can do it manually by checking the Pusher Debug Console, if you load the page with the Pusher Debug Console open you’ll see the connection logged. The Pusher JavaScript library provides a log property that you can assign a function to and then you can manually check to make sure a connection has been established by inspecting the browser’s JavaScript console. Or you can check the connection programmatically by monitoring the connection state of the Pusher instance.

pusher_001

The Pusher Debug console

Whatever you choose to do, you’ll now be connected.

Subscribe

Pusher uses the Publish & Subscribe pattern, so to receive data from Pusher you first need to subscribe to it. Pusher uses the term channels when it comes to subscriptions, so let’s subscribe to a channel called ‘test-channel’.

As with connection state, you can check the status of a subscription in a few ways; using the Pusher Debug Console, by checking the output from ‘Pusher.log’ or by binding to the ‘pusher:subscription_succeeded’ event.

pusher_002

Using Pusher.log to log pusher-js library information

Bind to events

Those of you who use jQuery will probably be familiar with the idea of binding to events. jQuery does provide shortcuts for some events (e.g. ‘.onclick( )’) but you can also bind to events using ‘.bind(, )’. Pusher follows this convention and you can bind to events to be informed when something updates; when the connection state changes, when a subscription succeeds or when new application data is received. For this example, and with the realtime plugin, we’re interested primarily in the latter.

Let’s bind to a ‘test-event’ on the channel:

When binding to an event you simply identify the event by name and pass in a reference to a function that will be called when that event occurs (is triggered) on the channel.

If you have a Pusher account you can test that the ‘handleEvent’ function is called by using the Pusher Event Creator; enter ‘test-channel’ as the channel name, ‘test-event’ as the event name and some data (‘{ “some” : “data” }’) into the event data text area and click the submit button. You’ll then see the debug information, along with the data you entered, logged to the JavaScript console.

pusher_003 

Triggering an event from the Pusher Event Creator and logging it in the JavaScript console

Since the realtime jQuery plugin that we’re building doesn’t publish (trigger) data (it just consumes it) we won’t cover that here. But if you’re interested in finding out more checkout the Pusher server docs.

Displaying realtime updates

The next thing to consider is displaying the realtime data updates to the user.

For this we’ll need an idea for a simple application; having worked in finance for a few years I’m generally keen to avoid any type of financial example, but Bitcoin has made it interesting and relevant. So, let’s create a very simple display for showing Bitcoin prices.

Note: We’re going to use some fake data. Let’s make sure this doesn’t result in more Bitcoin panic selling!

First, let’s create some HTML where we’ll display the realtime prices. We can pre-populate the display with prices known at the time the page was loaded:

Bitcoin Fake Prices

LastLowHighVolume
BTC/USD61.157 USD51 USD95.713 USD66271 BTC / 4734629 USD

Let’s update the JavaScript to subscribe to a more appropriately named channel called ‘btc-usd’ and bind to a ‘new-price’ event:

The ‘data’ sent to the ‘handleEvent’ function should also be in a more appropriate format – here’s the JSON:

{"last": "last value","low": "low value","high": "high value","volume": "volume value"}

Now that we know this we can change the ‘handleEvent’ function to update the appropriate cell in the table:

function handleEvent( data ) {var cells = $( '#bitcoin_prices tbody tr td' );cells.eq( 1 ).text( data.last );cells.eq( 2 ).text( data.low );cells.eq( 3 ).text( data.high );cells.eq( 4 ).text( data.volume );}

If you now trigger a ‘new-price’ event on the ‘btc-usd’ channel, using the JSON we defined, the page will update to show the new values.

There are ways of both making this code nicer and, as the page grows to show more data, optimise things. But, we’re going to make it so that realtime data will be added to the page simply by applying markup.

Before we progress, let’s first add a bit of styling to the example. In the ‘’ add the following CSS:

As you can undoubtedly tell, I’m no designer. So please feel free to improve on this.

pusher_004

The “styled” Bitcoin Fake Prices application

Finally, restructure things so we’re set up for building the plugin.

  1. Create an ‘examples’ directory and within it a ‘bitcoin’ directory.
  2. Move the ‘example.html’ file to ‘examples/bitcoin’, rename it ‘index.html’.
  3. Create a ‘src’ directory at the top-level of the project.

The directory structure should now look as follows:

/
examples/
bitcoin/
index.html
src/

We’re now ready to define our realtime markup and build the realtime jQuery plugin.

Realtime markup

The first thing to highlight is that this isn’t a new idea — I worked for a company called Caplin Systems and in 2001 they had a technology known as RTML that let you markup a page so that realtime updates could be applied. The purpose here is to use jQuery to parse the page and then interpret the markup, resulting in subscriptions, event binding and ultimately live content being added to the page.

For our plugin we’ll use HTML5’s data-* attributes. These attributes don’t directly affect the layout or presentation of the page so they’re a great choice for our realtime markup.

The questions we now need to answer about the markup are:

  • Where do we put the Pusher application key?
  • How do we identify what channels should be subscribed to?
  • How do we identify the events that should be bound to on a channel?
  • How do we know what data to display in the page, and where?

The first one is relatively easy. Since we need to include our plugin JavaScript file we can add a ‘data-rt-key’ attribute to the ‘

So, from the script tag you can see we’re going to connect to Pusher using the key identified by ‘data-rt-key’. We’re going to subscribe to the ‘btc-usd’ channel and bind to the ‘new-price’ event. When an event is received we’re going to update the appropriate table cell based on the value indicated by ‘data-rt-value’; if the value of the attribute is ‘last’ then the value of the ‘last’ property is taken from the received ‘data’ object and displayed in the cell.

Hopefully what we are trying to achieve is now pretty clear. Let’s start looking at how to create a jQuery plugin.

jQuery plugin basics

The jQuery plugin creation docs are pretty good so I won’t go into the details here. We’ll simply concentrate on building the functionality that we need in our plugin.

Before we write any code we should consider how we want to use the plugin. The normal way a plugin functions is that you use jQuery to query the page, and then you execute the plugin functionality against the matched elements.

$( 'a' ).toggle();

The above code would find all ‘’ elements and then execute the ‘toggle()’ functionality on them — probably hiding all anchors, so not the most useful example you’ll ever see.

So, let’s say we would want to use the plugin as follows:

Podívejme se na vytvoření očekávané funkce.

Plugin v reálném čase

Nejprve vytvořte soubor 'realtime.jquery.js' v adresáři 'src'. Tento soubor bude obsahovat funkci pluginu. Pak jako výchozí bod našeho pluginu přidáme následující soubory:

( function( $) {$.fn.realtime = function() {console.log( 'realtime!' );console.log( $( this ).html() );}  ;} (jQuery)); 

Můžeme to dokonce i vyzkoušet. V 'příkladech / bitcoin / index.html' odeberte příklad plugin '

Pokud nyní aktualizujete stránku, zobrazí se "v reálném čase". přihlášen do konzoly JavaScript spolu s kódem HTML z adresy '

'prvek. To je skvělé, protože plugin funguje; úspěšně provádíme naši funkci pluginů na tabulce, kterou identifikujeme selektorem, který jsme předali do jQuery.

pusher_005

jQuery pluginy a knihovny třetích stran

Náš plugin v reálném čase závisí na knihovně třetí strany - knihovně JavaScript Pusher. Momentálně jej máme zahrnuto staticky v našem HTML, ale nechceme, aby to vyžadovalo použití pluginu. Takže ji dynamicky nahrajeme. jQuery poskytuje způsob, jak to snadno udělat ve formě '.getScript () funkce.

Takže načtěte verzi 2.0 knihovny JavaScript Pusher. Načteme hostovanou verzi HTTPS tak, aby prohlížeče byli spokojeni, pokud je plugin použit na stránce zobrazené přes protokol HTTPS (Chrome již blokuje pokusy o načtení skriptů hostovaných HTTP na stránkách HTTPS a Firefox to udělá Firefox 23 ). Chystám se zabalit načítání knihovny do funkce takto:

var libraryLoaded = false;function loadPusher() {$.getScript( "https://d3dy5gmtp8yhk7.cloudfront.net/2.0/pusher.min.js" ).done( pusherLoaded ).fail( function( jqxhr, settings, exception ) {console.log( 'oh oh! ' + exception );}  );} funkce pushherLoaded (skript, textStatus) {libraryLoaded = true; console.log ('loadedher.min.js načten:' + textStatus);} loadPusher (); 

Pokud znovu načtete stránku, bude do konzoly zaznamenána zpráva 'push loaded.min.js loaded: success'.

Jak jsme se vyvíjeli, je vždy dobré mít způsob zápisu informací, takže v tomto okamžiku vytvoříme jednoduchou funkci 'log', kterou můžeme použít, která se právě přihlásí do konzoly. Použijeme to nyní a také jej použijeme pro protokolování událostí Pusher. Plný zdroj pluginu je nyní:

( function( $ ) {function log( msg ) {console.log( msg );}var libraryLoaded = false;function loadPusher() {$.getScript( "https://d3dy5gmtp8yhk7.cloudfront.net/2.0/pusher.min.js" ).done( pusherLoaded ).fail( function( jqxhr, settings, exception ) {log( 'oh oh! ' + exception );}  );} funkce pushherLoaded (skript, textStatus) {libraryLoaded = true; Pusher.log = log; log (' realtime! '); log ($ (this) .html ());}; loadPusher ();} (jQuery); 

Také si všimnete, že jsme přiřadili funkci 'log' do vlastnosti 'Pusher.log'. To znamená, že vidíme interní knihovnu Pusher, stejně jako naši vlastní.

Kdy se máme připojit?

Vzhledem k asynchronní povaze načítání knihovny nemůžeme zaručit, že bude načteno, když bude náš plugin aktivován. Bohužel to dělá věci trochu složitější, než je ideální, ale pokusíme se je vyřešit co možná nejjednodušeji.

Musíme zkontrolovat, zda je knihovna načtena - a tudíž vlajka 'libraryLoaded' - a jednat správně; pokud je knihovna načtena, můžeme se připojit, pokud nemáme potřeba spustit spuštění, dokud to není. Z tohoto důvodu je více smysluplné vytvořit pouze Pusherovou instanci, když ji skutečně potřebujeme, což je, když se chceme skutečně přihlásit k odběru dat.

Podívejme se, jak to můžeme udělat:

var pending = [];function pusherLoaded( script, textStatus ) {libraryLoaded = true;while( pending.length !== 0 ) {var els = pending.shift();subscribe( els );}}function subscribe( els ) {}$.fn.realtime = function() {var els = this;if( libraryLoaded ) {subscribe( els );}else {pending.push( els );}};

Když je plugin nazvaný, zkontrolujeme příznak "libraryLoaded" a zjistíme, zda byla načtena knihovna JavaScript Pusher. Máme-li to dobré, jdeme a můžeme se přihlásit. Je-li stále ještě čeká, musíme předplatit předplatné. Děláme to tím, že stiskneme kolekci jQuery ('els') na pole 'čekající'.

Nyní připojte

Nyní, když víme, že knihovna JavaScript Pusher byla načtena a že se stránka chce přihlásit k odběru dat, můžeme vytvořit instanci "Pusher". Protože chceme pouze jednu stránku "Pusher" na stránku, kterou budeme sledovat Singleton vzor a mít "getPusher ()":

var pusher;function getPusher() {if( pusher === undefined ) {var pluginScriptTag = $("script[src$='jquery.realtime.js']");var appKey = pluginScriptTag.attr("data-rt-key");pusher = new Pusher( appKey );}return pusher;}

Tato funkce chytí značku skriptu pluginů vyhledáním značky s atributem 'src', který končí koncovým znakem 'jquery.realtime.js', a poté získá hodnotu atributu 'data-rt-key'. Potom vytvoří novou instanci "Pusher", která předá klíč. Jak již bylo uvedeno výše, vytvoření nové instance "Pusher" má za následek spojení s zdrojem dat, který se vytváří.

předplatit

Nyní můžeme použít funkci getPusher () kdykoli chceme přistupovat k instanci "Pusher". V našem případě jej chceme použít při analýze prvků pro určení odběru.

Aktualizujte funkci "objednat" zástupného symbolu a přidejte další funkce uvedené níže:

function subscribe( els ) {var channelEls = els.find( "*[data-rt-channel]" );log( 'found ' + channelEls.size() + ' channels' );channelEls.each( subscribeChannel );}function subscribeChannel( index, el ) {el = $( el );var pusher = getPusher();var channelName = el.attr( 'data-rt-channel' );var channel = pusher.subscribe( channelName );}function find( els, selector ) {var topLevelEls = els.filter( selector );var childEls = els.find( selector );return topLevelEls.add( childEls );}

Funkce "find" je užitečná funkce pro získání všech prvků z existující kolekce, která odpovídají danému selektoru pomocí '.filtr()', spolu se všemi potomky prvků, které používají '.nalézt()'. Tuto funkci používáme k nalezení všech prvků označených jako abonentní kanály (atribut "data-rt-channel") a pro každý z nich pak voláme "subscribeChannel". Tato funkce získává název kanálu, který se má přihlásit, a použije hodnotu při volání "pushher.subscribe (název_kanálu)", aby se skutečně přihlásil k odběru kanálu.

Svázat

Pak musíme nalézt všechny prvky označené jako události (atribut 'data-rt-event'), který bude vázán na:

function subscribeChannel( index, el ) {el = $( el );var pusher = getPusher();var channelName = el.attr( 'data-rt-channel' );var channel = pusher.subscribe( channelName );var eventEls = find( el, '*[data-rt-event]' );log( 'found ' + eventEls.size() + ' events' );eventEls.each( function( i, el) {bind( el, channel );} );}function bind( el, channel ) {el = $( el );var eventName = el.attr( 'data-rt-event' );channel.bind( eventName, function( data ) {displayUpdate( el, data );} );}function displayUpdate( el, data ) {}

Pro každý prvek události nalezneme volání vlastní funkce 'bind', která se váže na událost na kanálu pomocí 'channel.bind (eventName, eventHandler)'. Funkce obsluhy událostí je malý uzávěr, který nám umožňuje předat aktualizaci dat při přijetí a prvek události do funkce 'displayUpdate'.

Pokud to spustíme, vidíme z protokolování, že se vytváří spojení, nacházíme jeden kanál a přihlašujeme se k němu a najdeme jednu událost, na kterou se chceme spojit.

pusher_006

jQuery v reálném čase zjišťování nálezů kanálů a vázání událostí

Zobrazit aktualizaci

Při volání obslužného programu událostí musíme najít název každé vlastnosti na objektu 'data' (např. Poslední, nízké, vysoké a hlasitosti) odeslané s aktualizací a najít všechny prvky označené tímto názvem.

function bind( el, channel ) {el = $( el );var eventName = el.attr( 'data-rt-event' );channel.bind( eventName, function( data ) {displayUpdate( el, data );} );}function displayUpdate( el, data ) {for( var propName in data ) {var value = data[ propName ];var updateEls = find( el, '*[data-rt-value="' + propName + '"]' );log( 'found ' + updateEls.size() + ' "' + propName + '" elements to update' );updateEls.text( value );}}

Otočíme se přes objekt 'data' a získáme název každé vlastnosti. Jakmile známe název vlastnosti ('propName'), nalezneme přidružené prvky a aktualizujeme jejich textovou hodnotu novou hodnotou dat. Nyní nebudeme podporovat objekty s jakoukoliv hierarchií - chceme jen jednu úroveň klíčových a hodnotových párů.

Pokud nyní aktualizujete stránku a spustíte událost z Pushman Event Creator, nové údaje budou okamžitě zobrazeny na stránce.

Pracovali jste s živou datovou službou? Jaké lekce jste se naučili? Dejte nám vědět v komentářích.

Doporučený snímek / náhled, živý obrazový obrázek přes Shutterstock.