JavaScript programozási nyelv - jQuery könyvtár

JQuery bővítmények (plugin)

Bevezetés

A jQuery JavaScript-könyvtár elsődleges célja, hogy gyors és tömör alternatívát nyújtson a többi elérhető, nyílt forrású JavaScript-könyvtárhoz képest. Ennek a célnak az elérésében kulcsfontosságú, hogy a jQuery magja a legtöbb fejlesztő igényeit kielégítse, miközben gyors és tömör marad. A fejlesztőknek ugyanakkor lehetnek olyan igényeik is, amelyeket a jQuery magja nem elégít ki tökéletesen, egyes programozók pedig írhatnak olyan bővítményeket a maghoz, amelyek a jQuery-felhasználók jelentős részének hasznosnak bizonyulhatnak, de nem célszerű bekerülniük a jQuery magjába. A jQueryt úgy tervezték, hogy többféleképpen is bővíthető legyen. JQuery bővítmények találhatók például a következő címeken:

Saját jQuery-bővítmény írása

Ha nem találtunk a céljainknak megfelelő bővítményt, akkor írhatunk egy sajátot, valamint ha úgy érezzük, hogy ez mások számára is hasznos lehet, akkor ezt érdemes közzétenni.
A jQueryt úgy tervezték, hogy nagyon egyszerűvé tegye a bővítmények megírását. A meglevő jQuery objektumot tagfüggvényekkel (method) vagy függvényekkel (function) bővíthetjük. Egyszerűen csak be kell vezetnünk a következő JavaScript kódokat a jQuery központi könyvtárának betöltése után:

jQuery.fn.goShop = function(){ return this.each(function(){ jQuery(’body’).append(’< div >Purchase: ’ + this.innerHTML + ’< / div >’); }); };

A bővítmény eléréséhez meg kell hívni a jQuery-t és meg kell adni az új tagfüggvény nevét:

jQuery(’p’).goShop();

Ebben a példában az történik, hogy a < p > tag-ekben szereplő szövegrészeket hozzá fűzi újra az eddigi tartalomhoz.

A jQuery-tagfüggvények egymáshoz láncolhatók, így felhasználhatják a jQuery-kijelölőket. A jQuery-tagfüggvényeket úgy határozzuk meg, hogy a tagfüggvény nevével bővítjük a jQuery.fn objektumot. Mivel a jQuery objektumnak több eredmény kezelésére is képesnek kell lennie, kódunkat egy each() függvényhívásba kell burkolnunk, hogy minden eredményre lehessen alkalmazni.

Egyedi jQuery függvények írása

A függvények a fő jQuery objektumhoz kapcsolódnak. A függvényeket arra szánták, hogy egy jQuery-kijelölőn kívülről hívjuk meg őket:

jQuery.checkout = function(){ jQuery(’body’).append(’< h1 >Checkout Succesful< / h1 >’); };

Ezt a függvényt is a szokványos módon hívhatjuk meg:

jQuery.checkout();

Ez a lehetőség, hogy új tagfüggvényeket és függvényeket csatolhatunk a fő jQuery objektumhoz a jQuery-felhasználóknak, valamint a bővítmények felhasználóinak gyors és tömör formában adhatnak új szolgáltatásokat a kódhoz. Azt, hogy valaki a jQueryt új tagfüggvénnyel vagy függvénnyel bővíti e maga dönti el. Általában a tagfüggvényen keresztüli bővítés a célszerűbb, mert ezeket az új tagfüggvényeket a meglévőkhöz láncolhatjuk, és így a tagfüggvény kódja a jQuery kijelölő motorjára támaszkodhat.

Kapcsolók átadása a bővítménynek

A kapcsolókat (option) egy kapcsoló objektumon keresztül a legcélszerűbb átadni egy egyedi bővítmény tagfüggvényének. Ha a paraméterek átadására csak egy kapcsoló objektumot használunk, akkor tisztább, könnyebben használható, és később rugalmasabban alakítható kódot kapunk.
Ha egy bővítményben kapcsolókat használunk, érdemes ésszerű alapértelmezéseket megadni hozzá. Ebben az esetben az is lényeges, hogy a bővítmény biztosítson egy olyan tagfüggvényt a felhasználónak, amivel felülbírálhatja az alapértelmezéseket. Mindkét célnak könnyedén eleget tehetünk azzal, ha bevezetünk egy alapértelmezett kapcsoló objektumot, a jQuery extend() tagfüggvényt és segítségével felülírjuk az alapértelmezett kapcsolókat a felhasználó által megadott értékekkel, majd az új kapcsolóértékeket használjuk fel a kódban:

jQuery.fn.pulse = function (options){ //átadott kapcsolók összefűzése az alapértelmezésekkel var opts = jQuery.extend({},jQuery.fn.pulse.defaults, options); return this.each(function (){fadeto //pulzálás for(var i = 0; i < opts.pulses; i++){ jQuery(this).fadeTo(opts.speed, opts.fadeLow).fadeTo(opts.speed, opts.fadeHigh); } //visszaállítás alaphelyzetbe jQuery.fadeTo(opts.speed, 1); }); }; //pulse bővítmény alapértelmezett beállításai jQuery.fn.pulse.defaults = { speed: "slow", pulses: 2, fadeLow: 0.2, fadeHigh: 1 };

A példában lévő fadeTo() függvény segítségével lehet egy elem áttetszőségét állítani, jelen esetben amit a pulse függvény meghívásakor megadunk neki, páldául a p elem ('p').

Az alapértelmezett kapcsolóértékeknek köszönhetően a bővítményünket felhasználó fejlesztők tetszőleges számú kapcsolót adhatnak meg a függvény meghívásakor. Lényeges, hogy az alapértelmezéseket a bővítmény belépési tagfüggvényének meghatározása után helyezzük el, különben hibát kapunk:

//csak egy beállítást bírálunk felül jQuery(’p’).pulse({pulses: 6}); //minden beállítást felülbírálunk jQuery(’p’).pulse({speed: „fast”, pulses: 10, fadeLow: 0.3, fadeHigh: 0.8});

Azzal, hogy a kapcsolókat egy olyan objektum formájában határozzuk meg, amelyet gyermekként csatolunk a bővítményfüggvényhez, az alapértelmezett kapcsolókat csak egyszer kell felülbírálni a kódban. A fejlesztő így megadhatja a saját alapértelmezett kapcsolóit, minimálisra csökkentvea kívánt viselkedés eléréséhez szükséges kód mennyiségét.
A kapcsolók használata egy bővítményben nagy rugalmasságot biztosít, így valószínűbb, hogy nagyobb közönség igényeit is elégíti ki mivel több feladatot képesek elvégezni. Továbbá az alapértelmezett kapcsolók halmazának megadása ugyancsak nagyobb rugalmasságot biztosít és ráadásul meg van az az előnye, hogy a bővítmény mindig támaszkodhat bizonyos értékekre.

A $ rövidítés használata az egyedi bővítményekben

A $ jelet sok JavaScript-könyvtár alkalmazza különféle célokra, azonban a jQuery csak a jQuery nevű központi objektum rövidítéseként használja. Ha a jQueryt együttműködő módba (compatibility mode) állítjuk, a $ álnév vezérlését átadja az azt eredetileg meghatározó könyvtárnak. A bővítmények szintén felépíthetők úgy, hogy ezt a módszert alkalmazzák.
Ha a bővítményünket egy névtelen függvénybe burkoljuk, és ezt a függvényt azonnal végrehajtjuk, a $ rövidítés a bővítményen belül marad, így a bővítményen kívüli kód a $-t a neki megfelelő szerepben használhatja. A bővítményen belül a $ a szokványos módon a jQuery objektumra hivatkozik:

;(function($) $.fn.pulse = function(options){ … //ugyanaz, mint az előző példa csak a jQuery objektum helyén $ jel van })(jQuery);

A függvény meghatározás elején látható pontosvessző azok ellen a fejlesztők ellen nyújt védelmet, akik elfelejtették kitenni a záró pontosvesszőt a saját könyvtárukban. A JavaScript nyelv alapértelmezés szerint új utasítást kezd a sortöréseknél, de sokan használnak olyan sűrítő eszközöket, amelyek a teljes JavaScript kódot egyetlen fájlba tömörítik. Ez az eljárás azonban eltávolítja a sorvégeket, és hibákat okozhat, ha a kódunk közvetlenül utána következik. A nyitó pontosvessző hozzáadása egyszerű és gyors módja annak, hogy védekezzünk ez ellen a lehetőség ellen.
A nyitó zárójel azonnal megkezdi a névtelen függvény meghatározását. A névtelen függvényünkön belül egy olyan függvényt határozunk meg, amely azt a változót adja át, amelyet a teljes névvel megadott jQuery objektum helyett használni szeretnénk. Ebben az esetben a $ jelet szeretnénk változóként használni. Az újabb függvény meghatározása amiatt szükséges, ahogy a JavaScript nyelv a hatóköröket kezeli. Az olyan hagyományosabb nyelvekben, mint a Java vagy a C++, a hatókör az utasításblokkra korlátozódik, míg a JavaScriptben függvényekbe burkoljuk. A függvény használatának célja itt tehát az, hogy beállítsunk egy hatókör korlátot, amelyen belül meghatározhatjuk a bővítményünket.
Ez után a bővítményünk új változata következik, amelyben az egyetlen változás a jQuery objektum használatának módja. Mivel a bővítményt egy névtelen függvénybe burkoltuk, és korlátoztuk a $ változó hatókörét, a $ elemet szabadon használhatjuk, anélkül, hogy az bármilyen más kóddal ütközne.
Az utolsó sor lezárja a hatókört megadó, illetve a névtelen függvényt egy záró kapcsos, illetve kerek zárójellel. Az utolsó utasítás az, amelyik ténylegesen meghívja a névtelen függvényünket rögtön annak meghatározása után. Itt utasítjuk a függvényünket a jQuery objektum átadására, amelyet a függvényünkben $-ra neveztünk át. Végül lezárjuk az utasítást egy pontosvesszővel, hogy védekezzünk a JavaScript tömörítési hibák ellen.
A $ rövidítés rendkívül hasznos lehet, amikor JavaScript kódot írunk: csökkenti a kód méretét, elősegíti a helyes kódfelépítést, és népszerű, jól ismert megoldás. Emiatt sok könyvtár használja a saját környezetének megfelelően. Mivel minden könyvtár a $ rövidítés saját változatát támogatja, könnyen adódhatnak ütközések. Azzal, hogy a bővítményünk kódját egy névtelen függvénybe burkoljuk, biztosíthatjuk, hogy a bővítmény a $ rövidítés használatát egy bizonyos szintű hatókörre korlátozza, ami csökkenti a más JavaScript könyvtárakkal való ütközés esélyét.
A bővítmény névtelen függvénybe burkolásának egyik mellékhatása, hogy létrejön egy záradék. A záradék használata a JavaScriptben segít, hogy megfelelő névtérhez rendeljünk olyan tagfüggvényt vagy változót, amelyet esetleg meg kell határoznunk, ami tovább csökkenti a változó- és függvénynevek más kódokkal való ütközésének veszélyét.

Privát függvények beágyazása saját bővítményekbe

A privát függvényeket a szokványos módon határozhatjuk meg azon a névtelen függvényen belül, amelybe a bővítményünket burkoltuk. Mivel a privát függvényt egy névtelen függvény zárja magába, a külső kódok nem fogják látni. A külső kódok számára csak azok a függvények vagy tagfüggvények lesznek láthatók, amelyek a jQuery objektumhoz kapcsolódnak (az előző példa kiegészítése, csak a változást írom le):

… return this.each(function (){ doPulse($(this), opts); }); }; function doPulse($obj, opts){ for(var i = 0; i < opts.pulses; i++){ $.fadeTo(opts.speed, opts.fadeLow).fadeTo(opts.speed, opts.fadeHigh); } …

Mivel a bővítményünket egy névtelen függvénybe burkoltuk, a privát függvények meghatározása a bővítményen belül mindössze annyiból áll, hogy a szokásos módon hozzáadunk egy új függvényt. A bővítmények nyilvános és privát tagfüggvényekbe rendezése számos előnnyel jár mind a bővítmény szerzője, mind a bővítmény felhasználói számára. Ahogy a bővítmény egyre érettebbé válik, és visszajelzéseket kapunk a közösségtől, a nyilvános és privát tagfüggvények segítségével következetes alkalmazásprogramozási felületet alakíthatunk ki a bővítmény egyes változatai között. Az API következetessége kiemelt fontosságú lehet a bővítmény sikerében.
Az a lehetőség, hogy a kódot nyilvános és privát elemekre bonthatjuk, a kód szervezése szempontjából is jelentős előnnyel jár a bővítmény fejlődése során. A jól szervezett kódot könnyebb áttekinteni, karbantartani és tesztelni, a megfelelően tesztelt, tiszta kód pedig kevésbé hajlamos a hibákra.

A metadata bővítmény támogatása

Több bővítmény is a metadata bővítmény segítségével ad át egyedi kapcsolókat a tagfüggvényeinek. A metadata bővítmény felhasználása a bővítmény felhasználása mindössze annyiból áll, hogy ellenőrizzük, hogy a bővítmény elérhető-e, majd kiegészítjük a bővítmény kapcsolóit a metaadat paraméterekkel. Ezzel a módszerrel alapértelmezett beállításokat adhatunk át, amikor meghívjuk a bővítményt, illetve felülbírálhatjuk azokat bármely objektum esetében, amelyen műveleteket kívánunk végezni, a jelölőnyelvi kódba írt metaadatok segítségével (megint az új sorokkal bővítem az eddigi példát):

//metadata bővítmény betöltése < script type=”text/javascript” src=”metadata/jquery.metadata.js”>< / script> //Példa metaadatokat tartalmazó leírókódra < p class=”{pulses: 8, speed: ’slow’}”>Starship Enterprise< / p> < p >Battlestar Galactica< / p > < p class=”{speed: 100}”>Serenity< / p > ;(function($){ … return this.each(function (){ //a metaadat elemek összefésülése erre a konkrét csomópontra var o = $.metadata ? $.extend({}, $.metadata.get(this)) : opts; doPulse($(this), opts); …

A metadata bővítmény beépítése nagyszerű példája annak, hogy miként építhetnek egymásra a jQuery bővítmények. A jQuery bővítményrendszere hatalmas, ezért nagy az esély rá, hogy találunk felhasználható bővítményeket.
A metadata bővítmény beépítéséhez és használatához először be kell töltenünk a bővítményt a parancsfájlunkba. A metadata bővítménynek a jQuery-vel együtt a Google Code ad otthont. A metadata bővítmény úgy működik, hogy lehetővé teszi további adatok beágyazását a HTML-kódba, miközben továbbra is érvényes HTML-t állít elő. Ezt úgy használjuk ki, hogy megengedjük a felhasználóknak, hogy elemfüggő beállításokat ágyazzanak be a kívánt elemek osztályelemébe.
A kapcsolók beágyazása a HTML-be szabványos JSON útján történik. Csak a felhasználók döntésétől függ, hogy minden kapcsolót beágyaznak-e, vagy mondjuk egyet sem. A metadata bővítmény felhasználására több más módszer is létezik, amelyeket a bővítmény dokumentációs oldala (http://docs.jquery.com/Plugins/Metadata) ismertet.
A bővítményünkön belül először megvizsgáljuk, hogy a felhasználó betöltötte-e a metadata bővítményt. Ezzel gondoskodunk róla, hogy ez a kiegészítő lehetőség elhagyható legyen, és szükség esetén biztosítsuk a visszairányú megfelelőséget. Mivel a metadata bővítmény egyetlen elemen végez műveleteket, a kapcsolók kezelésének módját felosztjuk. Az első lépés a bővítmény meghívásakor átadott kapcsolóknak a használata. Ezeket aztán kiegészítjük az alapértelmezett kapcsolóinkkal, amivel létrehozzuk a bővítményünk első példányosításának kiindulópontját. A második lépés ezeknek a helyileg alapértelmezett kapcsolóknak a bővítése az egyes elemekre esetleg meghatározott metadatokkal. Ahhoz, hogy a helyileg alapértelmezett kapcsolókat kibővítsük a metaadat kapcsolókkal, csak annyi szükséges, hogy a metadata bővítmény létezzen.

Statikus függvény hozzáadása saját bővítményhez

Ahhoz, hogy egy bővítményhez hozzáadhassunk egy statikus tagfüggvényt, a jQuery objektumot kell bővítenünk, nagyon hasonlóan ahhoz, ahogy egy tagfüggvényt adnánk hozzá. A különbség csupán abban áll, hogy a függvényeket jQuery kijelölők nélkül hívjuk meg:

… //visszaállítás alaphelyzetbe $obj.fadeTo(opts.speed, 1); } //statikus függvény $.pulse.impulse = function($obj){ var opts = { speed: 2500, pulses: 10, fadeLow: 0.2, fadeHigh: 0.8 }; doPulse($obj, opts); } //statikus függvény $.pulse.warpspeed = function($obj){ var opts = { speed: 25, pulses: 100, fadeLow: 0.2, fadeHigh: 0.8 }; doPulse($obj, opts); } //pulse bővítmény alapértelmezett beállításai …

A bővítményben rendelkezésre álló statikus függvények meghívása nagyon egyszerű. Csupán annyit kell tennünk, hogy kifejezetten átadunk egy érvényes objektumot, amelyen műveleteket szeretnénk végezni:

// az impulse tagfüggvény meghívása az első visszaadott elemre jQuery.pulse.impulse(jQuery(’p:first’)); // a warpspeed tagfüggvény meghívása az első visszaadott elemre jQuery.pulse.warpspeed(jQuery(’p:first’));

Egy statikus függvény hozzáadása a bővítményünk hatókörén belül csak annyit igényel, hogy módot teremtsünk arra, hogy a külső kódok meghívhassák. Ezt úgy érjük el, hogy a függvényt a jQuery objektumhoz kapcsoljuk.
A fenti példában egy névtér objektum létrehozásával segítettük a kód jobb rendszerezését. Ha a bővítményünk mindössze egyetlen statikus függvényt igényel, tökéletesen megfelel az is, ha névtér objektum hozzáadása nélkül tesszük elérhetővé a statikus függvényt. A névtér objektum hozzáadása után egyszerűen (a szokásos módon) meghatározzuk a függvényeinket, és a létrehozott névtér objektumhoz kapcsoljuk azokat. Ezzel a függvényeink elérhetővé válnak a globális névtér számára, miközben a bennük levő kód hozzáférhet a privát függvényekhez és változókhoz.
A statikus függvény használatba vétele mindössze annyiból áll, hogy meghívjuk a jQuery objektum segítségével, amelyhez hozzákapcsoltuk. A függvény meghívása jQuery kijelölők nélkül történik, ezért ahhoz, hogy műveleteket végezhessünk egy DOM elemen, az elemet kifejezetten át kell adnunk a függvénynek.