Tämän vuoden tammikuussa jQuery julkisti uuden plugins rekisterin , joten nyt tuntui hyvältä aikaa kirjoittaa opetusohjelma yhdistää jQuery-plugin rakentaminen intohimoni - reaaliaikainen web-teknologia.

Reaaliaikainen web-teknologiat helpottavat helposti live-sisällön lisäämistä aiemmin staattisiin verkkosivuihin. Elävä sisältö voi tuoda sivun elävään, pitää käyttäjät pysyvästi ja poistaa tarpeen päivittää sivu säännöllisesti. Reaaliaikaiset päivitykset saavutetaan yleensä liittämällä tietolähteeseen, tilaamalla tiedot, jotka haluat lisätä sivulle ja päivittämällä sivun tietojen saapumisen jälkeen. Mutta miksi tätä ei voida saavuttaa yksinkertaisella sivun merkitsemisellä, jotta voidaan tunnistaa, mitä tietoja pitäisi näyttää ja missä? No, ehkä se voi!

jQueryn tagline on kirjoittaa vähemmän, tee enemmän . JQuery Realtime -laajennuksen tagline, jota aiomme rakentaa tähän oppaaseen, on kirjoittaa vähemmän, tehdä reaaliaikaisesti.

Tässä opetusohjelmassa luodaan jQuery-laajennus, jonka avulla on helppo lisätä reaaliaikaista sisältöä sivulle yksinkertaisesti lisäämällä merkinnät. Ensin selvitetään, miten käytät palvelua Pusher tilaamaan reaaliaikaiset tiedot. Sitten määritellään tapa merkitä HTML5-dokumentti, jossa on "data" -ominaisuuksia tavalla, jota reaaliaikainen jQuery-plugin voi kysyä ja muunnetaan reaaliaikaisiin datatietueisiin. Lopuksi luodaan jQuery-plugiini, joka käyttää attribuutteja tilattaessa tietoja ja näyttää päivitykset heti sivulta.

Jos haluat vain sukeltaa suoraan sinne, voit tarkastele demoa toiminnassa tai voit lataa koodi ja aloittaa hakkeroinnin.

Pusher perusasiat

Pusher on isännöi palvelua, jonka avulla reaaliaikaista sisältöä ja interaktiivisia kokemuksia on helppo lisätä web- ja mobiilisovelluksiin. Täällä aiomme yksinkertaisesti yhdistää, tilata joitain tietoja ja päivittää sivu, kun tiedot tulevat sisään.

Tämän osoittamiseksi luo tiedosto 'example.html' ja sisällytä Pusher JavaScript-kirjasto Pusher CDN: ltä. Tiedämme, että aiomme käyttää jQuery 2.0.0 -ohjelmaa, joten meidän on myös sisällytettävä tämä nyt:

Creating a realtime jQuery plugin | Webdesigner Depot

Kytkeä

Kun Pusher JavaScript-kirjasto on sisällytetty, voimme muodostaa yhteyden Pusheriin luomalla uuden 'Pusher' -esitteen ja siirtämällä sovellusavaimeen. Luo ylimääräinen "

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:

Katsotaanpa odotetun toiminnon luomista.

Reaaliaikainen plugin

Luo ensin "realtime.jquery.js" -tiedosto 'src' -hakemistossa. Tämä tiedosto sisältää plugin-toiminnon. Lisää sitten seuraava tiedosto pluginamme lähtökohtana:

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

Voimme jopa testata tämän nyt. Esimerkissä / bitcoin / index.html "poistaa esimerkkisovittimen"

Jos päivität sivun nyt, näet "reaaliajassa!" kirjautui JavaScript-konsoliin yhdessä HTML-koodin kanssa "

"elementti. Tämä on hienoa, koska se tarkoittaa, että plugin toimii; olemme onnistuneesti suorittaneet plugin-toiminnon taulukkoon, jonka valitsin tunnistaa jQuery-ohjelmaan.

pusher_005

jQuery-laajennuksia ja kolmannen osapuolen kirjastoja

Tosiaikainen plugin perustuu kolmannen osapuolen kirjastoon - Pusher JavaScript -kirjastoon. Tällä hetkellä olemme sisällyttäneet se staattisesti HTML-koodimme sisälle, mutta emme halua tehdä sitä vaatimusta plugin käytöstä. Joten, lataamme sen dynaamisesti. jQuery tarjoaa mahdollisuuden tehdä näin helposti ".getScript (): n muodossa. toiminto.

Joten, lataamme Pusher JavaScript -kirjaston version 2.0. Laitetaan HTTPS-isäntämä versio, jotta selaimet ovat tyytyväisiä, jos pluginamme käytetään HTTPS-palvelimella (Chromi jo estää yrityksiä ladata HTTP-isännöityjä komentosarjoja HTTPS-sivuilla ja Firefox tekee Firefox 23 ). Aion pakata kirjaston lataamisen funktioon seuraavasti:

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 );}  );} toiminto pusherLoaded (script, textStatus) {libraryLoaded = true; console.log ('pusher.min.js ladattu:' + textStatus);} loadPusher (); 

Jos lataat sivun uudelleen, pusher.min.js ladattu: menestys -sanoma tulee kirjautumaan konsoliin.

Kehitettäessä on aina hyvä saada tapa tallentaa tietoja, joten tässä vaiheessa luodaan yksinkertainen "log" -toiminto, jota voimme käyttää, joka kirjautuu vain konsoliin. Käytämme tätä nyt ja käytämme sitä myös Pusher-tapahtumien kirjaamiseen. Täydellinen plugin lähde on nyt:

( 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 );}  );} funktio pusherLoaded (script, textStatus) {libraryLoaded = true; Pusher.log = loki; log ('pusher.min.js ladattu:' + textStatus);} $. fn.realtime = function () {log (' reaaliaikainen! '); log ($ (tämä) .html ());}; loadPusher ();} (jQuery)); 

Huomaat myös, että olemme määrittäneet log-toiminnon "Pusher.log" -ominaisuuteen. Tämä tarkoittaa sitä, että voimme nähdä sisäisen Pusher-kirjastokirjaston sekä oman.

Milloin meidän pitäisi muodostaa yhteyden?

Kirjaston lataamattomasta luonteesta johtuen emme voi taata, että se on ladattu, kun pluginamme kutsutaan toiminnaksi. Valitettavasti tämä tekee asioista hieman monimutkaisemman kuin ihanteellinen, mutta yritämme ratkaista sen niin yksinkertaisella tavalla kuin mahdollista.

Meidän on tarkistettava, onko kirjasto ladattu - siis kirjastosiLoaded-lippu - ja toimivat asianmukaisesti; jos kirjasto on ladannut, voimme muodostaa yhteyden, jos se ei ole, meidän täytyy jäädä toteutus, kunnes se on. Tästä syystä on järkevämpää luoda vain Pusher-ilmentymä, kun me todella tarvitsemme sitä, jolloin haluamme todella tilata tietoja.

Katsotaanpa, miten voimme tehdä sen:

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 );}};

Kun plugin on kutsuttu, tarkistamme kirjastosiLoaded-lippuun, onko Pusher JavaScript kirjasto ladattu. Jos meillä on hyvä mennä ja voimme tilata. Jos se on edelleen odottamassa, meidän on jonotettava tilaukset. Teemme tämän painamalla jQuery-kokoelmaa ('els') 'odottamattomaan' ryhmään.

Yhdistä nyt

Nyt kun tiedämme, että Pusher JavaScript kirjasto on ladattu ja että sivu haluaa tilata tietoja, voimme luoda "Pusher" -esitteen. Koska haluamme vain yhden "Pusher" -esimerkin sivua kohti, seuraamme sitä Singletonin kuvio ja on '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;}

Tämä toiminto nappaa plugin-komentotiedoston tagin etsimällä tagia, jonka 'src' attribuutti päättyy "jquery.realtime.js" -tiedostoon ja sitten saa "data-rt-key" attribuutin arvon. Sitten se luo uuden 'Pusher' -esitteen, joka kulkee avaimessa. Kuten aiemmin keskusteltiin, uuden 'Pusher' -edellytyksen luominen johtaa yhteyden luomiseen tietojemme lähteeseen.

merkitä

Nyt voimme käyttää 'getPusher ()' -toimintoa milloin haluamme käyttää 'Pusher' -esimerkkiä. Meidän tapauksessamme haluamme käyttää sitä analysoimalla elementtejä tilausten määrittelemiseksi.

Päivitä paikkamerkin tilaaja -toiminto ja lisää seuraavat lisätoiminnot:

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 );}

Etsi-toiminto on hyödyllisyystoiminto, jolla saadaan elementtejä olemassa olevasta kokoelmasta, joka vastaa tietyn valitsimen avulla '.suodattaa()', yhdessä kaikkien elementtien jälkeläisten kanssa '.löytö()'. Käytämme tätä toimintoa löytääkseen kaikki merkityt elementit, jotka edustavat kanavointilaitteita (data-rt-channel-attribuutti) ja jokaiselle kutsumme sitten "subscribeChannel". Tämä toiminto erottaa tilattavan kanavan nimen ja käyttää arvoa "pusher.subscribe (channelName)", jotta se todellisuudessa tilisi kanavan.

Sitoa

Sen jälkeen meidän on löydettävä kaikki merkityt elementit, jotka edustavat tapahtumia ("data-rt-event" attribuutti) sidotakseen:

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 ) {}

Jokaiselle tapahtumaelementille löydämme kutsun omasta "sidonta" -toiminnosta, joka liittyy tapahtumaan kanavalla käyttäen "channel.bind (eventName, eventHandler)". Tapahtumanhallinta-toiminto on pieni sulkeminen, jonka avulla voimme siirtää datapäivityksen, kun sitä vastaanotetaan, ja tapahtuma-elementin "displayUpdate" -toimintoon.

Jos suoritamme tämän nyt voimme nähdä kirjautumisesta, että yhteys muodostetaan, löydämme yhden kanavan ja tilaamme sen ja löydämme yhden tapahtuman, johon sidotaan.

pusher_006

jQuery reaaliaikainen merkintä löytää kanavan tilaus ja tapahtumien sitominen

Näytä päivitys

Kun tapahtumakäsittelijää kutsutaan, meidän on löydettävä päivityksen yhteydessä lähetettävän "data" -objektin kunkin omaisuuden nimi (esim. Viimeinen, pieni, korkea ja volyymi) ja löydettävä kaikki kyseisellä nimellä merkityt elementit.

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 );}}

Piirretään tieto-objektin päälle ja saamme jokaisen omaisuuden nimen. Kun tiedämme omaisuuden nimen ('propName') voimme löytää niihin liittyvät elementit ja päivittää niiden tekstin arvon uudella datan arvolla. Nyt emme aio tukea objekteja, joilla on minkäänlaista hierarkiaa - haluamme vain yhden tason avain- ja arvopareja.

Jos nyt päivität sivun ja käynnistät tapahtuman Pusher Event Creatorista, uudet tiedot näkyvät heti sivulla.

Oletko työskennellyt live data -palvelun kanssa? Mitä opetuksia opit? Kerro meille kommentit.

Esitetty kuva / pikkukuva, live data image kautta Shutterstock.