Proiectul meu actual de la noul loc de munca este sa fac site-urile companiei sa mearga cross-browser. O ocazie perfecta de a testa cateva frameworkuri de Javascript de care am tot auzit (in mare pe Ajaxian), dar pe care nu am avut ocazia sa le folosesc.
Primele doua pe care le-am incercat au fost Prototype si Dojo Toolkit, fiind cele mai complete solutii la ora actuala. Contrar asteptarilor, nu am incercat partea de Ajax, pentru ca nu am nici un proiect in lucru care sa beneficieze de asa ceva. Ma intereseaza mai mult partea de evenimente si manipulare a DOM-ului, pentru a decupla cat mai mult JS-ul de restul continutului si a lucra cat mai neinvaziv cu putinta.
Intr-un final am ales Dojo pentru ca este in general mult mai completa si are functii avansate despre care puteti afla cel mai bine ascultand interviul cu Alex Russel din podcasturile Ajaxian.
Selectarea elementelor din DOM
Indiferent de libraria pe care as fi ales-o, nici una nu beneficiaza de suport intern pentru selectarea elementelor din DOM folosind selectori CSS. Cele mai cunoscute metode sunt Behaviour si cssQuery (independente de framework), degrader (permite folosirea de expresii regulate), event:Selectors (integrat cu Prototype) si jQuery.
Acestea permit, de la caz la caz, gasirea elementelor pe baza selectorilor CSS (cssQuery) aplicarea de metode pe toate aceste elemente, sau atasarea directa de evenimente (Behaviour, event:Selectors).
jQuery
Cea mai placuta surpriza am avut-o experimentand un pic cu jQuery. Ceea ce parea la inceput o alta metoda de a cauta elementele din pagina, este de fapt o mini-librarie cu functii foarte utile care permite obtinerea majoritatii efectelor din framework-urile in toata regula cu un minim de cod. De fapt, asta e punctul forte al jQuery.
Exemplul pe care il voi da (inspirat de Suckerfish dropdowns) este un caz clasic pentru ceea ce inseamna progressive enhancement cu ajutorul javascript. Dupa cum stim, Internet Explorer nu suporta pseudo-clasa :hover decat pentru elementul a (linkuri), insa pentru CSS-uri avansate am avea nevoie de el pentru mult mai multe elemente. Solutia cea mai buna este de a defini in CSS o clasa "virtuala" pentru IE, care este aplicata elementelor vizate in mod dinamic, prin intermediul evenimentelor onMouseOver si onMouseOut. Pentru un buton CSS-ul ar arata cam asa:
input.button {
border: 1px solid green;
background-color: lightgreen;
color: green;
}
input.button:hover, input.button.sfhover {
background-color: green;
color: lightgreen;
cursor: pointer;
}
Iata cum ar arata codul Javascript in varianta folosirii Dojo+Behaviour (de notat ca nu putem folosi selectori multipli):
var myrules = {
'input.button': function(el) {
dojo.event.connect(el, 'onmouseover', function(evt){
dojo.html.addClass(el, 'sfhover');
});
dojo.event.connect(el, 'onmouseout', function(evt){
dojo.html.removeClass(el, 'sfhover');
});
}
}
Behaviour.register(myrules);
Si iata cum se face acelasi lucru cu jQuery:
$('input.button').hover(function(){
$(this).addClass('sfhover');
}, function() {
$(this).removeClass('sfhover');
});
In afara de avantajele unei solutii integrate (o librarie de 10K in loc de 2 insumand cateva sute de K) si de faptul ca scriem cod mult mai putin, jQuery este chiar mai avansat, pentru ca functia $() prin care se selecteaza elementele din pagina suporta cautarea de elemente multiple — $('input.button, #nav li') — sau chiar fragmente de cod XPath, lucru nesuportat de Behaviour.
Un mare avantaj este ca daca dorim sa folosim toate functiile oferite de un framework complex, cum este Dojo, putem folosi jQuery doar pentru functiile avansate de selectare, acesta conlucrand foarte bine cu Dojo. Iata o combinatie intre cele de mai sus, in care jQuery a luat locul Behaviour (sa presupunem ca jQuery nu ofera functiile add si remove class):
$('input.button, #nav li').hover(function(){
dojo.html.addClass(this, 'sfhover');
}, function() {
dojo.html.removeClass(this, 'sfhover');
});
Comments (4)
SI eu folosesc jQuery alaturi de Prototype dar am intampinat o problema la jQuery. Poate reusesti sa ma ajuti tu.
Problema, am folosit pluginul ajax din jquery si mai exact metoda $.post. Asta intoarce intr-o functie un obiect xml ce poate fi solosit cu $(xml) pentru procesare. Dar de exemplu folosesc $(xml).find('ajaxerror') si gaseste tagurile ajaxerror din raspuns. Dar daca dau sa gaseasca mai departe alte taguri, ele exista in raspuns, acestea numai sunt gasite. Daca nu dau sa caute taguri ajaxerror atunci pot sa gasesc alte taguri. Dar din moment ce fac o cautare iar nu pot gasi alte taguri.
Ai intampinat cumva aceasta problema?
Nu am cautat in obiecte xml, desi stiu ca se poate. Sa nu fie vreo eroare in cautarea de tag-uri ajaxerror, dupa care functia sa nu mai lucreze mai departe.
Iti sugerez doua lucruri:
1. folseste extensia FireBug pentru un debug mai exact, ca sa incerci sa-ti dai seama de unde vine.
2. scrie pe mailing listul de la jquery.com (http://jquery.com/discuss/ ) — autorul este foarte prompt in raspunsuri.
PS: oricum apar niste probleme cand folosesti jQuery alaturi de prototype, sa nu fie de acolo.
Salutare,
Parerea mea e ca daca folosesti Prototype, jQuery e deja in plus.
De prin martie suporta si el inlantuiri de genul "$('foo').show().stuff()" si selectari de genul "$$('form#foo input[type=text]')".
Bafta,
Vlad (fost vecin din Tineretului)
Am vazut si eu ca in 1.5.0 Prototype si-a simplificat mult modelul de eventuri si query-uri, insa versiunea aia nu e inca publica si nu inteleg de ce. In plus, cautam ceva foarte simplu (si mic) pentru query-uri DOM si jquery a picat la tanc.
Cand o sa ma lupt cu lucruri mai complicate, sunt convins ca tot la Prototype sau Dojo o sa ajung, pana atunci insa… jQuery, baby