Ocak ayında bu yıl jQuery yeni bir tarih duyurdu eklentileri Şimdi, gerçek zamanlı web teknolojileri - benim tutku ile jQuery eklenti bina birleştiren bir öğretici yazmak için çok güzel bir zaman gibi görünüyordu.

Gerçek zamanlı web teknolojileri, daha önce statik web sayfalarına canlı içerik eklemeyi gerçekten kolaylaştırır. Canlı içerik bir sayfayı canlı duruma getirebilir, kullanıcıları koruyabilir ve sayfanın periyodik olarak yenilenmesi ihtiyacını kaldırabilir. Gerçek zamanlı güncellemeler genellikle bir veri kaynağına bağlanmak, sayfaya eklemek istediğiniz verilere abone olmak ve daha sonra veri geldiğinde sayfayı güncellemek ile elde edilir. Ancak bu, neyin nerede gösterilmesi gerektiğini ve nerede gösterileceğini belirlemek için bir sayfanın işaretlenmesiyle neden elde edilemez? Eh, belki olabilir!

jQuery'nin sloganı daha az yazmak, daha fazlasını yapmak . Bu derste inşa edeceğimiz jQuery Realtime eklentisinin sloganı daha az yazılacak, gerçek zamanlı olacak.

Bu derste, bir sayfa işaretlemesi ekleyerek bir sayfaya gerçek zamanlı içerik eklemeyi gerçekten kolaylaştıran bir jQuery eklentisi oluşturacağız. İlk olarak, bir servisin nasıl kullanılacağını ele alacağız itici gerçek zamanlı verilere abone olmak. Daha sonra bir HTML5 belgesini 'data- *' öznitelikleriyle işaretleyerek, daha sonra gerçek zamanlı jQuery eklentimiz tarafından sorgulanıp gerçek zamanlı veri aboneliğine dönüştürülebilecek bir yol tanımlayacağız. Son olarak, verilere abone olmak ve sayfa içinde güncellemeleri anında görüntülemek için nitelikleri kullanacak olan jQuery eklentisini oluşturacağız.

Sadece dümdüz dalış yapmak isterseniz bir demo görüntüle hareket halinde veya yapabilirsiniz kodu indir ve hack yapmaya başla.

İtici temelleri

Pusher, web ve mobil uygulamalara gerçek zamanlı içerik ve etkileşimli deneyimler eklemeyi kolaylaştıran bir hizmettir. Burada basitçe bağlanacağız, bazı verilere abone olacağız ve daha sonra veriler geldiğinde sayfayı güncelleyeceğiz.

Bunu göstermek için 'example.html' adlı bir dosya oluşturun ve Pusher CDN'sinden Pusher JavaScript kitaplığını ekleyin. JQuery 2.0.0'ı kullanacağımızı biliyoruz, bu yüzden şimdi şunu eklemeliyiz:

Creating a realtime jQuery plugin | Webdesigner Depot

bağlamak

İtici JavaScript kütüphanesi eklendikten sonra yeni bir 'İtici' örneği oluşturarak ve uygulama anahtarını geçerek Pusher'e bağlanabiliriz. Ek oluştur

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:

Beklenen işlevselliği yaratmaya bakalım.

Bir gerçek zamanlı eklenti

Öncelikle 'src' dizininde bir 'realtime.jquery.js' dosyası oluşturun. Bu dosya eklenti işlevselliğini içerecektir. Ardından, aşağıdakileri dosyamıza eklentinin başlangıç ​​noktası olarak ekleyin:

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

Bunu şimdi bile test edebiliriz. 'Example / bitcoin / index.html dosyasında' örnek eklentiyi kaldırın '

Sayfayı yenilerseniz şimdi 'gerçek zamanlı' görürsünüz. JavaScript konsoluyla birlikte HTML’den

'öğe. Bu eklentinin çalıştığı anlamına gelir; eklenti işlevlerimizi jQuery'ye ilettiğimiz seçici tarafından belirlenen tabloda başarıyla yürütüyoruz.

pusher_005

jQuery eklentileri ve 3. parti kitaplıkları

Bizim gerçek zamanlı eklenti 3. parti kütüphanesi - Pusher JavaScript kütüphanesine dayanır. Şu an için bizim HTML'mize statik olarak dahil ettik, ancak eklentiyi kullanmak için bunu yapmak istemiyoruz. Yani, dinamik olarak yükleyelim. jQuery, bunu '.getScript ()' biçiminde kolayca yapmanın bir yolunu sağlar. işlevi.

Yani, Pusher JavaScript kütüphanesinin 2.0 sürümünü yükleyelim. HTTPS tarafından barındırılan sürümü, eklentimiz HTTPS üzerinden sunulan bir sayfada kullanılıyorsa tarayıcıların mutlu olması için yüklenir (Chrome zaten HTTPS sayfalarında HTTP tarafından barındırılan komut dosyalarını yüklemeyi durdurur ve Firefox şunları yapar: Firefox 23 ). Kütüphaneyi aşağıdaki gibi bir fonksiyona yükleyeceğim:

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 );}  );} function pusherLoaded (komut dosyası, textStatus) {libraryLoaded = true; console.log ('pusher.min.js yüklendi:' + textStatus);} loadPusher (); 

Sayfayı yeniden yüklerseniz, 'pusher.min.js yüklendi: başarı' mesajı konsola kaydedilir.

Gelişmekte olduğumuzdan, bilgileri kaydetmenin bir yoluna sahip olmak her zaman iyi bir şeydir, bu yüzden bu noktada, sadece konsola günlük olarak kayıt yapabileceğimiz basit bir 'log' fonksiyonu oluşturalım. Bunu şimdi kullanacağız ve ayrıca itici olayları günlüğe kaydetmek için kullanacağız. Eklentinin tam kaynağı şu an:

( 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 );}  );} function pusherLoaded (komut dosyası, textStatus) {libraryLoaded = true; Pusher.log = günlüğü; günlüğü ('pusher.min.js yüklendi:' + textStatus);} $ .fn.realtime = function () {log (' realtime! '); log ($ (this) .html ());}; loadPusher ();} (jQuery)); 

Ayrıca 'log' işlevini 'Pusher.log' özelliğine atadığımızı fark edeceksiniz. Bu, dahili Pusher kütüphanesinin yanı sıra kendi kayıtlarımızı da görebileceğimiz anlamına geliyor.

Ne zaman bağlanmalıyız?

Kütüphanenin yüklenmesinin asenkron doğası gereği, eklentimiz harekete geçtiğinde yükleneceğini garanti edemeyiz. Ne yazık ki bu, işleri ideal olmaktan biraz daha karmaşık hale getiriyor ama bunu olabildiğince basit bir şekilde çözmeye çalışacağız.

Kütüphanenin yüklü olup olmadığını kontrol etmeliyiz - dolayısıyla 'libraryLoaded' bayrağı - ve uygun şekilde hareket etmeli; Eğer kütüphane yüklüyse, bağlanana kadar yürütmeyi kuyruğa almamız gerekmiyorsa, bağlantı kurabiliriz. Bu nedenle, gerçekten ihtiyacımız olduğunda sadece Pusher örneğini yaratmak daha mantıklıdır, yani, gerçekten de veriye abone olmak istediğimizde.

Şimdi bunu nasıl yapabileceğimize bakalım:

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

Eklenti çağrıldığında, Pusher JavaScript kitaplığının yüklü olup olmadığını görmek için 'libraryLoaded' işaretini kontrol ederiz. Eğer gitmemiz gerekiyorsa ve üye olabiliriz. Hâlâ beklemede kalırsa, abonelikleri sıraya koymamız gerekir. Bunu jQuery koleksiyonunu ('els') 'bekleyen' bir diziye iterek yaparız.

Şimdi bağlan

Artık, Pusher JavaScript kütüphanesinin yüklendiğini ve sayfanın abone olmak istediğini bildiğimiz için 'İtici' örneğimizi oluşturabiliriz. Çünkü biz sadece sayfa başına bir 'Pusher' örneği istiyoruz. Tekton desen ve bir 'getPusher ()' var:

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

Bu işlev, 'jquery.realtime.js' ile biten bir 'src' özniteliğine sahip bir etiket arayarak eklenti kod etiketini alır ve ardından 'data-rt-key' özniteliğinin değerini alır. Daha sonra anahtarda geçen yeni bir 'İtici' örneği oluşturur. Daha önce tartışıldığı gibi, yeni bir 'İtici' örneği oluşturmak, oluşturulmuş verilerimizin kaynağına bağlı olarak sonuçlanır.

Abone ol

Şimdi 'İtici' örneğine erişmek istediğimiz zaman 'getPusher ()' işlevini kullanabiliriz. Bizim durumumuzda, abonelikleri belirlemek için öğeleri ayrıştırırken kullanmak istiyoruz.

Yer tutucu 'abone' işlevini güncelleyin ve aşağıda gösterilen ek işlevleri ekleyin:

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

'Bul' işlevi, varolan bir koleksiyondaki herhangi bir öğeyi kullanarak belirli bir seçici ile eşleşen bir yardımcı işlevdir. '.filter ()', kullanarak öğelerin herhangi bir torunu ile birlikte '.find (). Bu işlevi, kanal abonelikleri ('data-rt-channel' özniteliği) temsil edecek şekilde işaretlenmiş öğeleri bulmak için kullanırız ve her biri için 'subscribeChannel' olarak adlandırırız. Bu işlev, abone olunacak kanalın adını çıkarır ve kanalda gerçekten abone olmak için 'pusher.subscribe (channelName)' çağrılmasında değeri kullanır.

bağlamak

Ardından, aşağıdakileri temsil edecek olayları ('data-rt-event' özelliği) temsil edecek şekilde işaretlenmiş öğeleri bulmamız gerekir:

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

Bulduğumuz her etkinlik öğesi için 'channel.bind (eventName, eventHandler)' kullanarak kanaldaki olaya bağlanan kendi 'bind' fonksiyonumuzu çağırıyoruz. Olay işleyici işlevi, alındığında veri güncellemesini ve olay öğesini bir 'displayUpdate' fonksiyonuna geçirmemizi sağlayan küçük bir kapaktır.

Bunu şimdi çalıştırırsak, bir bağlantının kurulduğunu görerek, bir kanal bulup ona abone olduğumuzu ve bağlanması gereken bir olay bulduklarını görebiliriz.

pusher_006

jQuery gerçek zamanlı işaretleme kanalı abonelik ve olay bağlama bulma

Güncellemeyi görüntüle

Olay işleyicisi çağrıldığında, güncellemeyle birlikte gönderilen 'veri' nesnesindeki (örneğin son, düşük, yüksek ve hacimdeki) her bir özelliğin adını bulmalı ve bu isimle işaretlenmiş öğeleri bulmalıyız.

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

'Veri' nesnesini örteriz ve her mülkün adını alırız. Özellik adını ('propName') öğrendikten sonra ilişkili öğeleri bulabilir ve metin değerini yeni veri değeriyle güncelleyebiliriz. Şimdilik, herhangi bir hiyerarşi ile nesneleri desteklemeyeceğiz - sadece bir seviye anahtar ve değer çiftleri istiyoruz.

Şimdi sayfayı yeniliyor ve Pusher Event Creator'dan bir olay tetikliyorsanız, yeni veriler sayfada hemen görüntülenecektir.

Canlı veri servisi ile çalıştınız mı? Hangi dersleri öğrendin? Yorumlarda bize bildirin.

Öne çıkan görsel / küçük resim, canlı veri görüntüsü Shutterstock üzerinden.