DEFINE: to geek = to turn someone into a geek
TODO: Internet Explorer 6 trebuie ucis!
DEFINE: to geek = to turn someone into a geek
TODO: Internet Explorer 6 trebuie ucis!
Dacă te întrebi la ce or fi bune plugin-urile astea jQuery, îți voi spune eu: îți permite extinderea întregii librării jQuery prin adăugarea de noi metode și funcții la aceasta. De exemplu, ai putea crea un plugin care, printr-un singur apel, va parcurge toate link-urile unei pagini, și la fiecare link către un fișier PDF va adăuga o iconiță descriptivă. Apelul va arăta ceva în genul:
$("a").adaugaIconitaPDF();
Idei pentru plugin-uri sunt multe, prea multe chiar, și ca să te convingi poți intra pe pagina de plugin-uri jQuery unde le vei găsi ordonate după categorie. La momentul actual, acolo sunt 3684 de plugin-uri! Deci idei sunt cu tonele, și tot apar plugin-uri zi de zi. Așa că, ori poți sta să cauți plugin-ul care-ți trebuie, ori poți învăța să creezi propriile plugin-uri, lucru despre care voi discuta în următoarele câteva articole.
Pentru început, e nevoie de puțină teorie interesantă. În caz că nu știai deja, jQuery e renumit pentru faptul că poate fi folosit cu ajutorul unui singur caracter: simbolul dolar ($). De puține ori, însă, vei da peste probleme folosind simbolul $, fiindcă nu este singurul framework care face uz de acest simbol. Așa că, pentru a evita conflicte, când este cazul, se poate folosi cuvântul “jQuery“. De exemplu:
jQuery("a").fadeIn();
jQuery.variabila = 2;
Acum să îți spun și care sunt acele puține cazuri când pot apărea conflicte cu simbolul $: când creezi plugin-uri, și când folosești încă un framework împreună cu jQuery, de exemplu ExtJS + jQuery. Știind acum aceste lucruri, să începem cu plugin-urile! Pentru a putea crea plugin-uri, e nevoie să știi jQuery, evident, și care sunt obiectele extensibile din jQuery:
Ca să fiu sigur că nu mă vei pierde, îți voi explica ce reprezintă metodele și funcțiile. Dacă ai deja experiență în programarea orientată pe obiecte, poți sări peste paragraful acesta. Deci, metodele pot fi apelate direct, fără a instanția o clasă. Funcțiile, pe de altă parte, pot fi apelate doar asupra unui obiect ce reprezintă o instanță a unei clase. Dacă nu știi nici ce reprezintă instanțierea, e cazul să te oprești aici și să iei un tutorial de POO în C++ sau orice alt limbaj vrei.
Știind acum ce obiecte jQuery pot fi extinse, voi crea un simplu plugin care afișează un mesaj la încărcarea unor elemente HTML. Apelul va fi simplu:
$.mesaj("mesaj la comanda"); //metodă
$("div").mesaj("m-am incarcat"); //funcție
Și acum iată codul, trivial de altfel:
//codul pentru metodă
jQuery.mesaj = function(msg) {
alert(msg);
};
//codul pentru funcție
jQuery.fn.mesaj = function(msg) {
alert(msg);
}
Ți se pare complicat ? Dacă da, e grav, fiindcă în următoarele articole se mai complică, fiindcă voi discuta despre:
Probabil știi deja că unul din avantajele jQuery este înlănțuirea metodelor. Dacă nu știai, hai să-ți explic pe scurt cam ce e: odată ce ai folosit un selector, poți manipula acel selector într-o singură linie de cod, de exemplu:
$("#container").find("#obj1").css({ opacity: 0 }).fadeTo(400, 1).end().find("#obj2")
Așadar, toate metodele apelate mai sus vor afecta ultimul obiect HTML selectat cu jQuery. În cazul de mai sus, metoda find va acționa asupra obiectului container, apoi metodele css, fadeTo și end vor acționa toate, pe rând, asupra obiectului #obj1, ș.a.m.d. În alte limbaje de programare nu am văzut facilitatea asta, fiind nevoit să apelezi pe câte o nouă linie o altă metoda asupra aceluiași obiect.
În caz că ești curios, codul de mai sus caută obiectul HTML cu id-ul container, apoi caută printre descendenții (copii) acestuia elementul #obj1 pe care îl ascunde cu metoda css setându-i transparența maximă, apoi îl reafișează puțin câte puțin scăzând transparența într-un interval de 400ms, apoi metoda end se întoarce la ultimul obiect HTML găsit înaintea lui #obj1, și anume #container, după care caută printre descendenții săi obiectul #obj2.
Acum, revenind la oile noastre, o practică foarte bună a tuturor programatorilor este să scrie codul cât mai clar, citeț, ușor de urmărit. În cazul nostru, JavaScript ne permite scrierea codului de mai sus în felul următor:
$("#container").find(#"obj1")
.css({ opacity: 0 })
.fadeTo(400, 1)
.end()
.find("#obj2")
Crede-mă, te va ajuta enorm când vei umbla prin fișierele JavaScript pentru a depista erori, de exemplu, sau când vei încerca să-ți reamintești de ce ai făcut ce ai făcut.
Gata. În sfârșit am reușit să mă mut la casă pe pământ. De când așteptam momentul ăsta! Da, am revenit să continui ce am început, să vă ajut cu sfaturi în programarea web, să vă aduc noutăți, review-uri, ș.a.m.d.
În ciuda faptului că mă voi cam axa pe jQuery o perioadă de timp, asta nu înseamnă că va fi un blog numai despre jQuery. Va fi despre mult mai multe, dar sunt încă la început cu el așa că s-o luăm încet.
Ce-am mai făcut între timp:
O perioadă nu voi mai posta nimic pe blog fiindcă mă aflu în mutări
Mă voi muta la casă pe pământ.. scap într-un final de oraș! Dar, ca să nu îmi pierd vizitatorii, am decis să dezvălui cu ce vă voi încânta pe viitor dacă veți urmări blogul meu:
…și multe altele! Astea au fost așa ca să vă atrag atenția, fiindcă abia am atins vârful iceberg-ului! Așa că nu mă părăsiți încă…
Zilele trecute am dat fără să vreau peste un articol legat de MooTools, un alt framework JavaScript. În articolul respectiv erau lăudate capabilitățile OO ale acestui framework. Se pare ca MooTools este un framework foarte orientat pe obiecte, ba mai mult, se pare că încurajează la maxim folosirea programării orientate pe obiecte (POO), lucru care m-a fascinat pe loc! Așadar, am început să răscolesc prin acest framework și am realizat că nu era nici pe departe la fel de tare ca jQuery. E drept că tot ce face jQuery se poate face și cu MooTools, însă nu la fel de repede și de ușor. Și aici au început problemele!
Mie îmi place la nebunie POO, iar jQuery se știe deja că nu oferă mai deloc suport pentru POO. Singura legătură pe care o are cu POO este funcția extend care este folosită deobicei la crearea plugin-urilor. În rest, nimic! Nu clase, nu interfețe, nu moștenire… toate se pot obține doar prin folosirea unor principii JavaScript care îți dau impresia că ai programa pe obiecte. Chiar și în JavaScript, POO este mai mult o improvizație posibilă datorită facilităților extraordinare ale acestui limbaj extrem de extensibil.
Revenind la jQuery și POO.. mi-a plăcut atât de mult MooTools din cauza acestui fapt, și m-am gândit: oare nu e posibil să amestec MooTools cu jQuery ? După îndelungi căutări, aflu că pot fi oarecum amestecate, în sensul că ești nevoit să separi codul MooTools de codul jQuery, lucru care nu mă ajută absolut deloc. Eu vreau să pot folosi cod jQuery în cod MooTools, beneficiind astfel de facilitățile OO oferite de cel din urmă. Eh, am dat și peste plugin-uri jQuery care încearcă să ofere astfel de facilități, dar sunt cam varză.
Demoralizat după atâtea căutări zadarnice, când să renunț dau peste ceva numit DUI (Digg User Interface). Se pare că cei de la Digg s-au trezit în aceeași situație în care mă aflu eu acum, iar ca rezolvare au considerat că mai bine să implementeze ei un model OO pentru jQuery, sub numele DUI. Evident, au reușit, însă nu este ce-mi doream eu. De ce ? Fiindcă este o soluție destul de rudimentară, adică oferă suport doar pentru clase, singleton, și cam atât. Eu am nevoie de interfețe, moștenire, ș.a.m.d. Ce mă fac ? Digg a spus clar că framework-urile JS OO nu s-au dovedit a fi o soluție practică.
După mai multe căutări, am dat în cele din urmă peste o librărie JS care oferă facilități OO adevărate: JS.Class. Este exact ce aveam nevoie: are suport pentru clase, interfețe, moștenire, reflexii, și câte și mai câte. În sfârșit mi-am găsit pacea! Acum mai urmează să văd ce poate face și să-l scot la un test drive
Am descoperit adineauri pe twitter un tip care e maniac jQuery, ca mine așa. Și am găsit la el un site super tare, care este de fapt o galerie uriașă de site-uri care folosesc jQuery. Este nemaipomenit, mai ales că fiecare intrare din galerie are și codul sursă complet pentru intrarea respectivă
Site-ul de care vorbesc este acesta. E superb, mai ales dacă ai nevoie de inspirație pentru efecte sau… look-uri! Vizualizare plăcută!
În articolul precedent arătasem care sunt cei mai rapizi selectori jQuery, iar acum îți voi mai da un sfat care să facă orice selector mai rapid cu 25% decăt era (dar ordinea performanței va rămâne aceeași, adică primează selectorul de ID, apoi cel de tag + clasă, apoi cel de tag, apoi cel de clasă.
<p>$("div.clasa_mea", "#element_parinte");</p>
Să explic acum de ce codul de mai sus e super super rapid. În primul rând, să explic sintaxa. jQuery acceptă și un al doilea parametru când se folosește un selector, reprezentând contextul în care se face căutarea propriu-zisă. Ce înseamnă asta ? În cazul de mai sus i-am spus lui jQuery să-mi caute elementul DIV cu clasa clasa_mea, dar să caute doar în cadrul elementului cu ID-ul element_parinte, în loc să caute tot DOM-ul cum ar fi făcut dacă nu s-ar fi precizat contextul căutării. De ce e super rapid ? În primul rând, jQuery procesează mai întâi contextul, și apelează funcția JavaScript getDocumentById( ), apoi începe căutarea în cadrul elementului găsit, căutând un element DIV ce are clasa clasa_mea. Deci e foarte rapid!
Evident că tot nu e mai rapid decât selectorul de ID. Acum precis te întrebi: dar dacă folosesc context la selectorul de ID, va fi mai rapid ? În ciuda faptului că ar părea logic, din păcate nu va fi mai rapid. Iată codul, și imediat explic și de ce:
<p>$("#myID", "#element_parinte");</p>
Dacă ai urmărit până acum ce am explicat, apelul de mai sus face două lucruri: caută elementul element_parinte cu viteza maximă a selectorului de ID, dar apoi mai face încă o căutare, cea a elementului myID. Chiar dacă va fi restrânsă căutarea doar în cadrul contextului, faptul că se mai face o căutare extra va adăuga câteva fracțiuni de secundă în plus la căutare, comparativ cu folosirea selectorului ID fără context care face doar o singură căutare.
Dacă folosești des selectorii jQuery, este bine să iei în considerare viteza cu care se execută diferitele tipuri de selectori. În continuare găsești cele 3 tipuri mari de selectori în ordinea performanței, primul fiind cel mai rapid:
$("#un_id"); // cautare dupa ID $("div"); //cautare dupa tag $(".clasa") //cautare dupa clasa
Acum, evident, urmează explicațiile. Selectorul de ID folosește funcția JavaScript getElementById( ) care e cea mai rapidă. Punct. Al doilea selector, cel de tag, este următorul cel mai rapid fiindcă folosește funcția JavaScript getElementByTagName( ) care e mai înceată decât prima. Ultimul selector, cel de clasă, este cel mai încet fiindcă nu folosește o funcție anume, ci traversează tot DOM-ul pentru a găsi ce trebuie. Dar, ca un sfat, poți folosi ultimii doi selectori într-unul singur, obținând astfel un selector mai rapid decat cel de tag:
$("div.clasa");
Bun, iată încă un sfat extrem de util din punctul de vedere al performanței (și, deci, a timpului de încărcare a unei pagini): a se evita selectarea unui obiect într-un loop. Iată un exemplu de cod ce trebuie evitat:
for (i=0; i<10000; i++) { var obj = $("#lista_ul"); obj.append( $("<li>Item " + i + "</li>") ); }
Bun, explicația e simplă. La fiecare iterație, jQuery este nevoit să caute toată structura DOM a paginii pentru a găsi mereu același obiect – este pur și simplu groaznic, și probabil execuția acelui cod va dura câteva secunde (depinde și de browser, ce-i drept). Așadar, pentru a evita astfel de întâmplări nefericite, iată cum trebuie remediat codul:
var obj = $("#lista_ul"); for (i=0; i<10000; i++) obj.append( $("<li>Item " + i + "</li>") );
De data asta, codul va fi executat de până la 5 ori mai repede. Cum așa ? Păi selectorul jQuery de ID folosit pentru a accesa elementul listă folosește, de fapt, funcția JavaScript getElementById( ) care va fi executată o singură dată, nu de 10000 de ori ca în primul exemplu! Acum, chiar și a doua bucată de cod are o problemă de performanță, pe care o voi discuta în următorul articol Best Practices pentru a face codul să fie chiar și mai rapid!
comentarii recente