Přejít k navigační liště

Zdroják » JavaScript » Novinky v jQuery 1.4

Novinky v jQuery 1.4

Články JavaScript, Různé

jQuery je velmi dobře známý, široce používaný a oblíbený JavaScriptový framework. Dnes, tedy 14.1.2010 by měla být uvolněna jeho verze s pořadovým číslem 1.4. Pojďme se proto aktuálně podívat, jaké novinky pro nás jeho tvůrce připravil, a s jakými změnami se budou muset programátoři vypořádat.

jQuery 1.4 má novou formu dokumentace API, kterou najdeme na adrese api.jquery.com. V nové dokumentaci je možné filtrovat metody podle verze, ve které se objevily. Pojďme se tedy podívat, co nás čeká za novinky ve verzi 1.4

Konvence: Protože framework jQuery je vlastně jen jeden objekt, který lze používat mnoha způsoby, bude v textu použita následující konvenci: Statická metoda je metoda, kterou voláme přímo nad jQuery objektem (např. jQuery.noConflic­t). Pokud bude řeč o metodě, myslí se tím metoda jQuery objektu, který dostaneme voláním $(„nějaký-selektor“) (např. $(„a“).addClas­s(„xy“)). Občas bude řeč o jQuery objektu jako o kolekci elementů, tím se myslí pouze to, že např. objekt který vrátí $(„a“) interně obsahuje kolekci všech DOM elementů <a/>.

Novinky v API

http://api.jquery.com/…version/1.4/

Více callback funkcí

Mnoho metod nyní přijímá jako parametr i callback funkci. Metody pak pracují tak, že callback fci. zavolají a výsledek použijí jako svůj běžný textový parametr.

V případě, že jQuery kolekce obsahuje více elementů (a má to smysl), aplikuje se callback funkce na každý element zvlášť. Toto je patrně nejzajímavější využití této novinky. Funkce je pak volána s jedním nebo dvěma parametry (podle smyslu). První je vždy index v rámci kolekce elementů a druhý pak zpravidla původní hodnota atributu, který metoda mění.

Týká se to metod: after( function ), .append( function(index, html) ), .prepend( function(index, html) ), .before( function ), .html( function(index, html) ), .text( function(index, text) ), .val( function ), .replaceWith( function ), .wrap( wrappingFunction ), .wrapAll( wrappingFunction ), .wrapInner( wrappingFunction ), .addClass( function(index, class) ).css( propertyName, function(index, value) )

Příklad při použití .addClass()

$('ul li').addClass(function(i) {
  return 'item-' + i;
});

Události

.live( eventType, [ eventData ], handler )

Live nyní umí předávat eventData stejně jako .bind(). Tato metoda byla kompletně přepsána a nyní podporuje více událostí. Konkrétně: submit, change, mouseenter, mouseleave, focus a blur.

Dvě nové události: .focusin() a .focusout()

Jedná se o alternativu k .focus() a .blur(). Na rozdíl od nich, události .focusin() a .focusout() probublávají a můžeme je zachytit i na potomcích.

Traversování „až po“

V metodách pro traversování přibyly tři nové metody: .nextUntil( [ selector ] ), .parentsUntil( [ selector ] ) a .prevUntil( [ selector ] ). Umožní zahrnout do jQuery kolekce všechny elementy až po podmínku vyjádřenou selektorem. Například:

<ul>
    <li class="prvni">1</li>
    <li class="druhy">1</li>
    <li class="treti">1</li>
    <li class="ctvrty">1</li>
</ul>
$(".prvni").nextUntil(".treti");
// bude obsahovat [<li class="prvni">, <li class="druhy>]

Pracujete s HTML a chtěli byste své weby dostat na vyšší úroveň? Přijďte na školení JavaScript a AJAX, které pořádá Akademie Root. Naučíte se, jak používat moderní funkce dnešních prohlížečů. Naučíme vás používat JavaSctipt a AJAX, tvořit základní skripty a ovládnout web pomocí nových vlastností.

Nové metody

.clearQueue( [ queueName ] )

Nová metoda, která vyprázdní frontu. Dříve bylo za tímto účelem nutno psát toto:

$("#test").queue(queueName, []); // nahrazení fronty novu prázdnou frontou

A přesně takto i vypadá implementace této nové metody.

.delay( duration, [ queueName ] )

Nová metoda delay pro přidání zpoždění do fronty. Parametr duration přímá i textová označení známá z efektů „fast“, „slow“ a pod.

Nyní je možné místo

$("#test")
    .fadeIn()
    .queue(function(){
        var el = $(this);
        setTimeout(function(){
            el.dequeue();
        }, 5000);
    })
    .fadeOut();

psát

$("#test").fadeIn().delay(5000).fadeOut();

.detach( [ selector ] )

Metoda pro vyjmutí jQuery kolekce elementů z DOM (zachová ale veškerá nastavení včetně data)

.unwrap()

Odstraní rodiče elementů (samotný element ale zachová). Funguje zhruba takto:

var x = $("#test");
x.parent().replaceWith(x);

.toArray()

Vrátí pole DOM elementů v jQuery kolekci. Má stejný výsledek jako .get() (bez parametru). toArray je ale jasnější název.

Nové statické metody

jQuery.contains( container, contained )

Nová statická metoda pro zjištění, jestli je nějaký DOM element uvnitř jiného:

jQuery.contains(document.documentElement, document.body); // true
jQuery.contains(document.body, document.documentElement); // false

S tímto souvisí i metoda .has( contained ), která má nově verzi s parametrem typu DOM.

jQuery.isEmpty­Object( object )

Statická metoda, která zkontroluje, jestli je daný objekt prázdný. Hodí se při práci s literálovým zápisem.

jQuery.isEmptyObject({}) // true
jQuery.isEmptyObject({ foo: "bar" }) // false

jQuery.isPlai­nObject( object )

Statická metoda, která zkontroluje, jestli zadaný objekt vznikl literálovým zápisem. Funguje na principu kontroly konstruktoru a prototypu objektu.

jQuery.proxy( function, scope ), jQuery.proxy( scope, name )

Implementace funkce „bind“ (nemá nic společného z .bind metodou jQuery), kterou možná znáte z jiných frameworků. Jako jeden z parametrů vezme funkci a vrátí novou, u které bude vždy zachován  obor platnosti (this bude reference na zadaný objekt – parametr scope – ať je volána odkudkoli a jakkoli).

 Uvažme následující příklad.

var obj = {
    name: "Jan Novák",
    test: function(){
        alert(this.name);
    }
};

Pokud bychom teď chtěli metodu obj.test volat po kliknutí na nějaký element, můžeme nyní psát.

$("#test").click( jQuery.proxy( obj, "test" ) );

Výhodné je také to, že jQuery.proxy při použití pro obsluhu události, zachová refernci na původní funkci. Prostě pro odstranění obsluhy události vzniklé pomocí jQuery.proxy můžeme použít přímo referenci na původní funkci. Nemusíme se starat o referenci na funkci, kterou vrátí jQuery.proxy.

$("#test").unbind( "click", obj.test );

jQuery.noop

Toto není nová metoda, ale nová vlastnost. Není to nic jiného, než prázdná funkce. Prostě

jQuery.noop = function (){};

Co se jinak nevešlo

.add( selector, context ), .closest( selector, [ context ] )

U Metody add a closest, které pracují se selektroem, je nyní možné specifikovat druhým parametrem context, ve kterém se bude selektor vyhodnocovat. Stejně tak jako tomu je u samotné $( selector, [context] ).

.offset( coordinates ), .offset( coordinates(index, coords) )

Metoda .offset nyní umožňuje i nastavení. Existuje i verze s callback parametrem (viz část „Více callback funkcí“).

.data( obj ), .data()

Metoda data umožňuje nyní pracovat přímo s objektovou strukturou a ne jen formou key – value, jak tomu bylo doposud.

$("#test").data({a: 1, b: 2});

$("#test").data(); // vrátí {a: 1, b: 2}

.index( selector ), .index()

Metoda index nyní kromě DOM elementu umí pracovat i přímo se selektorem, případně použije pro porovnání sousedy elementu. Složí k určení pozice elementu v jQuery kolekci vůči okolnímu DOMu.

jQuery()

Volání jQuery bez parametrů nyní vrátí prázdný jQuery objekt (s prázdnou kolekcí elementů).

jQuery( html, props )

Při vytváření DOM elementů z HTML kódu je nyní možné rovnou předat vlastnosti, které se budou na nově vzniklé elementy aplikovat

$("<div>", {
  "class": "test",
  text: "Click me!",
  click: function(){
    $(this).toggleClass("test");
  }
}).appendTo("body");

Co se API přímo nedotklo

Novinky v API jsou jen malá část změn, velká část jQuery byla kompletně přepsána a optimalizována. O všech novinách a změnách nás autoři budou informovat každý následující den po dobu 14 dnů pomocí stránky http://jquery14.com/. Už to naznačuje, že vydání verze 1.4 bude velmi zajímavé sledovat. Určitě se máme na co těšit.  Vždyť jQuery má právě 4. narozeniny.

 Popřejme mu vše nejlepší…

Komentáře

Subscribe
Upozornit na
guest
28 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Honza Marek

Škoda, že live neumožňuje zavolání funkce nad objektem, který byl právě načten nebo vytvořen. Tak jako je to možné pomocí pluginu livequery.

jtousek

A toto je možné jak? Tedy o kterou událost jde? Opravdu to není možní pomocí jQuery().live()?

virgee

$(„#novyElemen­t“).live(„clic­k“, function(){
alert(‚hello‘);
});

Ja ‚live‘ funkce pouzivam uz nejaky ten patek, a zatim mi to celkem spolehlive fungovalo i pro elementy, ktere na strance pribyly dodatecne. Asi myslite nejakou jinou vlastnost livequery pluginu.

Honza Marek

Jasně, tohle je základní vlastnost live eventů :)

Jde mi o tohle

$(".novyElement").livequery(function () {
    alert("Je tu nový element");
    $(this).addClass("...");
    ...
}); 
jtousek

Možná je to blbost, ale nespustí se při vytvoření elementu událost onload?
tedy:
$(„.novyElemen­t“).live(‚load‘, function () {
alert(„Je tu nový element“);
$(this).addClas­s(„…“);

});

Daniel Steigerwald

nespustí

blizzboz

celú noc som programoval v JS + jQuery a ráno sa pozerám na zdroják aby som si oddýchol a zase vidím článok o jQuery O_o

Michal Augustýn

Možná by stálo za zmínku, že John Resig dbá na zpětnou kompatibilitu, takže je možné, že přechod z 1.3 na 1.4 bude poměrně bezbolestný…

karf

Má zkušenost s upgradem mezi desetinkovými verzemi jQuery je přesně opačná. Většinou je to peklo. John Resig sice může dbát na zpětnou kompatibilitu, ale vývojáři pluginů už ne, takže vám jeden hloupě (nebo i chytře) napsanej plugin může rozbít celou aplikaci. Debugovat to není žádná zábava. A je už víceméně pravidlem, že po velké verzi jQuery následuje hned několik opravných verzí. Hodil by se spíš seznam nekompatibilit s předchozími verzemi.

Michal Augustýn

Hodil by se spíš seznam nekompatibilit s předchozími verzemi.
Tak jsem to myslel :)

KLoK

Opravte si „doposut“

Martin Malý

A kde přesně?

Dave

jeste FET na (nejspis) FEL
…Studuji Softwarové inženýrství na ČVUT FET. Pracuji…

Aichi

Zdá se to jenom mě, že jQuery učí lidi prasáctví? Samá anonymní funkce, pro tvorbu „tříd“ není využíváno objektové vlastnosti Javascriptu – prototype.

Pekelník

jquery učí lidi prasit, php učí lidi prasit, delphi učí lidi prasit, windows učí lidi prasit , ubuntu učí lidi prasit, bla bla bla…

c4tto

Můžete popsat, co je na anonymních funkcích prasáckého? V JS jsou proste funkce first class hodnoty, proto se taky tak používají. Nebo myslíte, že všechna volání funkcí s konstatními parametry by měla napsána tímto způsobem?

var prvniCislo = 3;
var druheCislo = 5;
func(prvniCislo, druheCislo);

Větší zdroják takto napsaný bych opravdu nechtěl číst.

Osobně mi v jQuery dost chybí možnost předat jako parametr scope, ve kterém se funkce volá, tak jako to je v ExtJS. To je podle mě opravdová překážka v pohodlném objektovém programování.

Aichi

Tak víceméně jste si odpověděl sám. Anonymní funkce v ovladačích událostí a jako callbacky, tak jak k nim navádí dokumentace zabraňují tomu aby lidi programovali objektově. Je z toho prostě hnusná přezávorkovaná špageta.

Martin Malý

Bez znalosti kontextu (možná to tu už padlo) se jen zeptám: Je nějaký důvod, proč by lidi v JavaScriptu měli „programovat objektově“ a ne „funkcionálně“? Když už teda JavaScript je funkcionální jazyk, a když je „objektovost“ v JS víceméně hackována přes prototypy? Je nějaký důvod nepoužívat přirozený rys jazyka (tedy „přezávorkované špagety“) a lámat je do objektů jen proto, že jsou objekty „IN“?

Daniel Steigerwald

Martine, Javascript je objektový i funkcionální jazyk zároveň. Není ale třídový. Nic jako třída v javascriptu není (i když se to mootools snaží simulovat).
Mimochodem, Prototype inheritance není hack javascriptu, ale jeho regulérní vlastnost. Slušné knihovny proto taky nedělají nic jiného, než že poskytují pro tuto funkcionalitu sugar methody. Někdy i velmi krátké: http://code.google.com/…goog/base.js?r=2

Odpověď na tvoji otázku, jestli sem ji pochopil dobře (proč v js nestačí {} a extend) je jednoduchá. Protože objektový model musí být živý. Přidáš-li prototype metodu, dost pravděpodobně chceš, aby ji měli i všechny, třeba již existující, instance. Nebo, rozšíříš-li Base Button např., nechceš znova překopírovat nové metody do všech potomků ručně, nebo snad ano? :)

Daniel Steigerwald

A ještě jedna poznámka. Otázka nestojí jestli funkcionálně, nebo objektově. Pro objektový model se hodí JS prototype, ale jinde zas najde využití funkcionální přístup. Např. closure, nebo předávání funkce referencí. Proto je JS tak flexibilní jazyk.

Martin Malý

Ne, ne, ne, když dovolíš, nepochopils. Reagoval jsem na Aichiho komentář, že „… zabraňuje lidem psát objektově“. A já se ptám, proč by mělo být nutné psát v JS objektově, když „objektové psaní JS“ je tak trošku hack přes prototypy (ne že by byl prototyp hack, tos zase špatně pochopil). Zkrátka jsem se ptal, proč není možné se smířit s tím, že JS je jazyk funkcionální s prototypy a psát podle toho (tedy se závorkama), a proč by „jiné než objektové“ psaní mělo být v JS považováno za „prasení“.

15. 1. 2010 6:35 redakčně upravil Martin Malý, důvod: Překlep ve jméně komentujícího
Daniel Steigerwald

Tak teď tvé otázce již vůbec nerozumím ;) Definujme si pojmy.

1) Co si myslíš že je, „objektové psaní“? Příklad kódu prosím.
2) O jakém hacku přes prototypy stále mluvíš? Máš na mysli to, co sem pastoval?
3) Co to znamená „psát se závorkama“? Jaké máš na mysli, hranaté, složené, nebo snad kulaté?
4) Co to je „jiné než objektové“ psaní?

Dokud si nevyjasníme tyhle čtyři body, tak tvé otázce vůbec nerozumím.

Martin Malý

Dej si prosím tu práci a nejprve si přečti, nač jsem reagoval: „Anonymní funkce v ovladačích událostí a jako callbacky, tak jak k nim navádí dokumentace, zabraňují tomu aby lidi programovali objektově. Je z toho prostě hnusná přezávorkovaná špageta.“ Pak si přečti mou otázku a pak odpověz.

Daniel Steigerwald

Ok, tak to zkusím postupně od začátku, abychom neztratili nit.

Zdá se to jenom mě, že jQuery učí lidi prasáctví? Samá anonymní funkce, pro tvorbu „tříd“ není využíváno objektové vlastnosti Javascriptu – prototype.

Nezdá se ti to, je to tak. Je to důsledek dlouhodobé Resigovi maniakální snahy ušetřit každý možný znak. Není to tak dávno, co prohlašoval, že žádná library nemá mít více jak 20KB. Teď, co má jQuery 23KB, tak snad poleví ;)

Ale vážně, ačkoliv interně je prototype pro jQuery objekt použit, do ostatních částí library prosakuje pomaličku. Je to dané historickým vývojem. Když nedržíte stav, nepotřebujete instance, stačí vám statické metody, tedy nepotřebujete prototype. Protože jQuery bylo dlouho pouze příruční DOM udělátko, aby člověk nemusel psát tolik kódu, jediný stav co byl držen, byly elementy vrácené dotazem do dokumentu. Sám Resig se dlouho použití prototype vyhýbal, jeho první příklad na implementaci Class (na blogu) nebyl prostý chyb (a vlastně dodnes je to dost problematický kus kódu)

Tedy, jelikož se Resig dlouho vyhýbal použití prototype, dával tím i špatný směr všem uživatelům. A jim to nevadilo, proč taky, na mousehover nějaký objektový model nepotřebujete.

Zde musím zmínit, v čem byly (a dodnes částečně jsou) Mootools tak revoluční. Třídy se používají všude. Třeba animace byla od začátku třída (funkce s prototype). Výhodou bylo, že animaci šlo libovolně zastavit, opět spustit atd. Oproti tomu jQuery, první implementace animace stav nedržela. Lehce si jde představit, co se stalo např. při násobném přejetí myšky přes tlačítko (spustilo se x animací, které se přebíjeli navzájem).

jQuery přístup není nutně špatný. Ovšem psát jQuery přístupem aplikaci, je cesta do pekel. To je asi ten hlavní rozdíl oproti Mootools. Kdo si přečetl zdroják, a držel se jeho stylu při psaní aplikace, tak jeho kód vypadal 2× lépe, než jQuery, a 5× lépe se udržoval ;)

Je nějaký důvod, proč by lidi v JavaScriptu měli „programovat objektově“ a ne „funkcionálně“? 

Dva hlavní důvody:
1) Funkcionálně v JS prostě neuděláš to, co objektové. Není to tak, nebo tak. Platí, co sem napsal výše. Objektový model musí být živý. Pomocí closure a {} sice namodeluješ lecos, ale živé to nebude.

2) Na přemíru použití anonymních funkcí doplatí čistota kódu, který se tak snadno může stát write-only. Platí to, co pro všechny ostatní jazyky. jQuery kód vede ke: http://en.wikipedia.org/wiki/Code_smell
Uvedu příklady:
Duplicate code, identical or very similar code exists in more than one location: když cpeš všechnu logiku do anonymní inline funkcí, tak ji těžko znovupoužiješ (DRY), jQuery se opakuje stále (i když v poslední době to je lepší)
Large method, function, or procedure that has grown too large: Všechny jQuery funkce, které svoje chování přizpůsobí typu předaného argumentu. O tom se dá diskutovat, jestli nejde o trade-off, ale vzhledem k tomu, že to žádná jiná library nedělá.. a mě osobně tahle funkce nikdy nechyběla.. myslím, že je to zbytečné.
Large class, a class that has grown too large, see God object: jQuery == God objekt
atd..

dark

Výborně napsané. Jde asi i o to, že někteří programátoři vůbec nedokážou překonat hranice. Kdo používal třeba qooxdoo, tak ví, o čem mluvím:)

Aichi

Jak pise pod/nad timto prispevkem Dan, JS je objektovy jazyk a zadny hacky pro objektove psani potreba nejsou.

Objekty je vhodne pouzivat uz jen pro to, ze v instancich si lepe uchovas stav aplikace, nez v nejakych globalnich vlastnostech, ktere predavas funkcim.

karf

Nevím, jestli jQuery učí lidi prasit, ale určitě se pomocí ní pouští do javascriptu i ti, co normálně neumí programovat. Samozřejmě pak vzniká špagetovej kód. Ale když si vzpomenu, jaké scripty se masově patlaly před jQuery (a obecně před knihovnami tohoto typu), tak to bylo mnohem větší peklo.

Mně na jQuery ta „neobjektovost“ taky celkem vadí, dneska má hlavně každej pocit, že se všechno musí napsat jako jQuery plugin, i když se to třeba vůbec nehodí.

Karel Minařík

> Zdá se to jenom mě, že jQuery učí lidi prasáctví? Samá anonymní funkce …

To je zajímavý názor do pranice :) Musím říct, že já sám jsem se docela bránil/bráním u větších věcí použít jQuery a preferuju Prototype/Scrip­taculous ( protože mi víc vyhovuje ten přístup „uděláme si z JavaScriptu Ruby“).

Ale když se _třeba_ podíváš na http://github.com/…s/quirkey.js, tak to velmi, velmi srozumitelný a dobře napsaný kus kódu. To by v Prototype nebylo nijak „lepší“. (Příkladů jsou jinak tisíce, tenhle mi ale přijde stále docela ilustrativní.)

Mně osobně teprve potom co jsem si přečetl http://jsninja.com od Johna Resiga došlo, jak to vlastně s jQuery myslel.

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.