Anda di halaman 1dari 144

Fundamentos de jQuery

ndice
1 Bienvenido/a
1.1 Obtener el Material de Aprendizaje
1.2 Softare
1.! A"adir #avaS$ript a una %&'ina
1.( )epura$i*n del +*di'o #avaS$ript
1., -jer$i$ios
1.. +onven$iones /tilizadas en el 0ibro
1.1 2otas de la 3radu$$i*n
1.4 Material de 5eferen$ia
2 +on$eptos B&si$os de #avaS$ript
2.1 6ntrodu$$i*n
2.2 Sinta7is B&si$a
2.! Operadores
2.!.1 Operadores B&si$os
2.!.2 Opera$iones $on 28meros y +adenas de +ara$teres
2.!.! Operadores 0*'i$os
2.!.( Operadores de +ompara$i*n
2.( +*di'o +ondi$ional
2.(.1 -lementos 9erdaderos y Falsos
2.(.2 9ariables +ondi$ionales /tilizando el Operador 3ernario
2.(.! )e$lara$i*n Sit$:
2., Bu$les
2.,.1 Bu$les /tilizando For
2.,.2 Bu$les /tilizando ;:ile
2.,.! Bu$les /tilizando )o<:ile
2.,.( Brea= y +ontinue
2.. %alabras 5eservadas
2.1 9e$tores
2.4 Objetos
2.> Fun$iones
2.>.1 /tiliza$i*n de Fun$iones
2.>.2 Fun$iones An*nimas Autoeje$utables
2.>.! Fun$iones $omo Ar'umentos
2.1? )etermina$i*n del 3ipo de 9ariable
2.11 0a palabra $lave this
2.12 Al$an$e
2.1! +lausuras
! +on$eptos B&si$os de jQuery
!.1 @Ado$umentB.readyAB
!.2 Sele$$i*n de -lementos
!.2.1 +omprobar Sele$$iones
!.2.2 Cuardar Sele$$iones
!.2.! 5efinamiento y Filtrado de Sele$$iones
!.2.( Sele$$i*n de -lementos de un Formulario
!.! 3rabajar $on Sele$$iones
!.!.1 -n$adenamiento
!.!.2 Obtenedores ACettersB D -stable$edores ASettersB
!.( +SSE -stilosE D )imensiones
!.(.1 /tilizar +lases para Apli$ar -stilos +SS
!.(.2 )imensiones
!., Atributos
!.. 5e$orrer el )OM
!.1 Manipula$i*n de -lementos
!.1.1 Obtener y -stable$er 6nforma$i*n en -lementos
!.1.2 MoverE +opiar y 5emover -lementos
!.1.! +rear 2uevos -lementos
!.1.( Manipula$i*n de Atributos
!.4 -jer$i$ios
!.4.1 Sele$$iones
!.4.2 5e$orrer el )OM
!.4.! Manipula$i*n
( -l n8$leo de jQuery
(.1 $ vs $()
(.2 MFtodos /tilitarios
(.! +omproba$i*n de 3ipos
(.( -l MFtodo )ata
(., )ete$$i*n de 2ave'adores y +ara$terGsti$as
(.. -vitar +onfli$tos $on Otras Bibliote$as #avaS$ript
, -ventos
,.1 6ntrodu$$i*n
,.2 9in$ular -ventos a -lementos
,.2.1 9in$ular -ventos para -je$utar una vez
,.2.2 )esvin$ular -ventos
,.2.! -spa$ios de 2ombres para -ventos
,.2.( 9in$ula$i*n de M8ltiples -ventos
,.! -l Objeto del -vento
,.( -je$u$i*n autom&ti$a de +ontroladores de -ventos
,., 6n$rementar el 5endimiento $on la )ele'a$i*n de -ventos
,.,.1 )esvin$ular -ventos )ele'ados
,.. Fun$iones Au7iliares de -ventos
,...1 $.fn.hover
,...2 $.fn.toggle
,.1 -jer$i$ios
,.1.1 +rear una HSu'eren$iaI para una +aja de 6n'reso de 3e7to
,.1.2 A"adir una 2ave'a$i*n por %esta"as
. -fe$tos
..1 6ntrodu$$i*n
..2 -fe$tos 6n$orporados en la Bibliote$a
..2.1 +ambiar la )ura$i*n de los -fe$tos
..2.2 5ealizar una A$$i*n +uando un -fe$to fue -je$utado
..! -fe$tos %ersonalizados $on $.fn.animate
..!.1 -asin'
..( +ontrol de los -fe$tos
.., -jer$i$ios
..,.1 Mostrar 3e7to O$ulto
..,.2 +rear un Men8 )esple'able
..,.! +rear un Slides:o
1 Aja7
1.1 6ntrodu$$i*n
1.2 +on$eptos +lave
1.2.1 C-3 vs. %OS3
1.2.2 3ipos de )atos
1.2.! Asin$ronismo
1.2.( %olGti$as de Mismo Ori'en y #SO2%
1.2., Aja7 y Firebu'
1.! MFtodos Aja7 de jQuery
1.!.1 @.aja7
1.!.2 MFtodos +onvenientes
1.!.! $.fn.load
1.( Aja7 y Formularios
1., 3rabajar $on #SO2%
1.. -ventos Aja7
1.1 -jer$i$ios
1.1.1 +ar'ar +ontenido -7terno
1.1.2 +ar'ar +ontenido /tilizando #SO2
4 -7tensiones
4.1 JQuF es una -7tensi*nK
4.2 +rear una -7tensi*n B&si$a
4.! -n$ontrar y -valuar -7tensiones
4.( -s$ribir -7tensiones
4., -s$ribir -7tensiones $on Mantenimiento de -stado /tilizando ;id'et Fa$tory de
jQuery /6
4.,.1 A"adir MFtodos a un ;id'et
4.,.2 3rabajar $on las Op$iones del ;id'et
4.,.! A"adir Fun$iones de )evolu$i*n de 0lamada
4.,.( 0impieza
4.,., +on$lusi*n
4.. -jer$i$ios
4...1 5ealizar una 3abla Ordenable
4...2 -s$ribir una -7tensi*n %ara +ambiar el +olor de Fondo en 3ablas
> Mejores %r&$ti$as para Aumentar el 5endimiento
>.1 Cuardar la 0on'itud en Bu$les
>.2 A"adir 2uevo +ontenido por Fuera de un Bu$le
>.! 2o 5epetirse
>.( +uidado $on las Fun$iones An*nimas
>., Optimiza$i*n de Sele$tores
>.,.1 Sele$tores basados en 6)
>.,.2 -spe$ifi$idad
>.,.! -vitar el Sele$tor /niversal
>.. /tilizar la )ele'a$i*n de -ventos
>.1 Separar -lementos para 3rabajar $on -llos
>.4 /tilizar -stilos en +as$ada para +ambios de +SS en 9arios -lementos
>.> /tilizar $.data en 0u'ar de $.fn.data
>.1? 2o A$tuar en -lementos no -7istentes
>.11 )efini$i*n de 9ariables
>.12 +ondi$ionales
>.1! 2o 3ratar a jQuery $omo si fuera una +aja 2e'ra
1? Or'aniza$i*n del +*di'o
1?.1 6ntrodu$$i*n
1?.1.1 +on$eptos +lave
1?.2 -n$apsula$i*n
1?.2.1 -l Objeto 0iteral
1?.2.2 -l %atr*n Modular
1?.! Cesti*n de )ependen$ias
1?.!.1 Obtener 5eLuire#S
1?.!.2 /tilizar 5eLuire#S $on jQuery
1?.!.! +rear M*dulos 5eusables $on 5eLuire#S
1?.!.( Optimizar el +*di'o $on las Merramientas de 5eLuire#S
1?.( -jer$i$ios
1?.(.1 +rear un M*dulo %ortlet
11 -ventos %ersonalizados
11.1 6ntrodu$$i*n a los -ventos %ersonalizados
11.1.1 /n -jemplo de Apli$a$i*n
12 Fun$iones y eje$u$iones diferidas a travFs del objeto $.Deferred
12.1 6ntrodu$$i*n
12.2 -l objeto diferido y Aja7
12.2.1 deferred.then
12.! +rea$i*n de objetos diferidos $on $.Deferred
12.!.1 deferred.pipe
12.!.2 $.when
1 6ntrodu$$i*n < Bienvenido/a
jQuery se est& $onvirtiendo r&pidamente en una :erramienta Lue todo desarrollador de
interfa$es eb deberGa de $ono$er. -l prop*sito de este libro es proveer un resumen de la
bibliote$aE de tal forma Lue para $uando lo :aya terminado de leerE ser& $apaz de realizar
tareas b&si$as utilizando jQuery y tendr& una s*lida base para $ontinuar el aprendizaje. -l
libro fue dise"ado para ser utilizado $omo material en un sal*n de $lasesE pero tambiFn
puede ser 8til para estudiarlo de forma individual.
0a modalidad de trabajo es la si'uienteN -n primer lu'ar se dedi$ar& tiempo a $omprender
un $on$epto para lue'o realizar un ejer$i$io rela$ionado. Al'unos de los ejer$i$ios pueden
lle'ar a ser trivialesE mientras Lue otros no tanto. -l objetivo es aprender a resolver de
manera f&$il lo Lue normalmente se resolverGa $on jQuery. 0as solu$iones a todos los
ejer$i$ios est&n in$luidas en el mismo material de aprendizaje.
Capitulo 1
1.1 Obtener el Material de Aprendizaje
-l material de aprendizaje y el $*di'o fuente de los ejemplos Lue se utilizan en el libro
est&n :ospedados en un repositorio de Cit:ub. )esde allG es posible des$ar'ar un ar$:ivo
.zip o .tar $on el $*di'o para utilizar en un servidor eb.
Si usted suele utilizar CitE es bienvenido de $lonar o modifi$ar el repositorio.
1.2 Softare
%ara trabajar $on los $ontenidos del libroE ne$esitar& las si'uientes :erramientasN
nave'ador eb Firefo7O
la e7tensi*n Firebu'E para Firefo7O
un editor de te7tos planos A$omo 2otepadPP/Sublime 3e7t 2 para ;indosE 'edit/Qate
para 0inu7 o3e7tMate para Ma$ OS RBO
para las se$$iones dedi$adas a Aja7N /n servidor lo$al A$omo ;AM% o MAM%B o un $liente
F3%/SSM A$omoFileSillaB para a$$eder a un servidor remoto.
1.! A"adir #avaS$ript a una %&'ina
-7isten dos formas de insertar $*di'o #avaS$ript dentro de una p&'inaN es$ribiendo $*di'o
en la misma Aen in'les inlineB o a travFs de un ar$:ivo e7terno utilizando la etiLueta s$ript.
-l orden en el $ual se in$luye el $*di'o es importanteN un $*di'o Lue depende de otro debe
ser in$luido despuFs del Lue referen$ia A-jemploN Si la fun$i*n B depende de AE el orden
debe ser AEB y no BEAB.
%ara mejorar el rendimiento de la p&'inaE el $*di'o #avaS$ript debe ser in$luido al final del
M3M0. Adem&sE $uando se trabaja en un ambiente de produ$$i*n $on m8ltiples ar$:ivos
#avaS$riptE Fstos deben ser $ombinados en un solo ar$:ivo.
Ejemplo de cdigo JavaScript en lnea
<script>
console.log('hello');
</script>
Ejemplo de inclusin de un archivo externo JavaScript
<script src='/js/jquery.js'></script>
1.( )epura$i*n del +*di'o #avaS$ript
0a utiliza$i*n de una :erramienta de depura$i*n es esen$ial para trabajar $on #avaS$ript.
Firefo7 provee un depurador a travFs de la e7tensi*n Firebu'O mientras Lue Safari y
+:rome ya traen uno inte'rado.
+ada depurador ofre$eN
un editor multi<linea para e7perimentar $on #avaS$riptO
un inspe$tor para revisar el $*di'o 'enerado en la p&'inaO
un visualizador de red o re$ursosE para e7aminar las peti$iones Lue se realizan.
+uando usted este es$ribiendo $*di'o #avaS$riptE podr& utilizar al'uno de los si'uientes
mFtodos para enviar mensajes a la $onsola del depuradorN
console.log() para enviar y re'istrar mensajes 'eneralesO
console.dir() para re'istrar un objeto y visualizar sus propiedadesO
console.warn() para re'istrar mensajes de alertaO
console.error() para re'istrar mensajes de error.
-7isten otros mFtodos para utilizar desde la $onsolaE pero estos pueden variar se'8n el
nave'ador. 0a $onsola adem&s provee la posibilidad de estable$er puntos de interrup$i*n y
observar e7presiones en el $*di'o $on el fin de fa$ilitar su depura$i*n.
1., -jer$i$ios
0a mayorGa de los $apGtulos $on$luyen $on uno o m&s ejer$i$ios. -n al'unosE podr& trabajar
dire$tamente $on Firebu'O en otros deber& es$ribir $*di'o #avaS$ript lue'o de in$luir la
bibliote$a jQuery en el do$umento.
A8n asGE para $ompletar $iertos ejer$i$iosE ne$esitar& $onsultar la do$umenta$i*n ofi$ial de
jQuery. Aprender a en$ontrar respuestasE es una parte importante del pro$eso de
aprendizaje.
-stas son al'unas su'eren$ias para :a$er frente a los problemasN
en primer lu'arE ase'8rese de entender bien el problema Lue est& tratando de resolverO
lue'oE averi'Te a LuF elementos tendr& Lue a$$eder $on el fin de resolver el problemaE y
determine $*mo a$$ederlos. %uede utilizar Firebu' para verifi$ar Lue esta obteniendo el
resultado esperadoO
finalmenteE averi'Te LuF ne$esita :a$er $on esos elementos para resolver el problema.
%uede ser 8tilE antes de $omenzarE es$ribir $omentarios e7pli$ando lo Lue va a realizar.
2o ten'a miedo de $ometer errores. 3ampo$o trate en el primer intento es$ribir de forma
perfe$ta su $*di'o. +ometer errores y e7perimentar $on solu$iones es parte del pro$eso de
aprendizaje y le ayudar& a Lue sea un mejor desarrollador.
%odr& en$ontrar en la $arpeta /ejercicios/soluciones ejemplos de solu$iones a los
ejer$i$ios del libro.
1.. +onven$iones /tilizadas en el 0ibro
-7isten una serie de $onven$iones utilizadas en el libroN
0os mFtodos Lue pueden ser llamados desde el objeto jQueryE ser&n referen$iados
$omo$.fn.nombreDelMetodo. 0os mFtodos Lue e7isten en el espa$io de nombres Aen
in'lFs namespa$eB de jQuery pero Lue no pueden ser llamados desde el objeto jQuery ser&n
referen$iados $omo $.nombreDelMetodo. Si esto no si'nifi$a mu$:o para ustedE no se
preo$upe U ser& m&s $laro a medida Lue vaya pro'resando en el libro.
Ejemplo de un cdigo
// el cdigo de ejemplo aparecer de esta forma
0as remar$a$iones apare$er&n de esta forma.
Nota
0as notas sobre al'8n tema apare$er&n de esta forma.
1.1 2otas de la 3radu$$i*n
)ebido a Lue el material tiene $omo fin el aprendizaje y la ense"anzaE el mismo se
en$uentra tradu$ido a espa"ol formal AustedB.
Mu$:os $on$eptos tF$ni$os son nombrados en su versi*n tradu$ida a espa"ol. Sin
embar'oE para tener de referen$iaE tambiFn se e7pli$a $omo es llamado en in'lFs.
0os ejemplos y solu$iones a ejer$i$ios no est&n $ompletamente tradu$idos. -sto es debido a
LueE $uando estF trabajando en un proye$to realE el $*di'o Lue en$uentre en otros sitios
probablemente estF en in'lFs. A8n asGE se :an tradu$ido los $omentarios in$orporados en
los $*di'os de ejemplos y al'unos te7tos parti$ulares para fa$ilitar la $omprensi*n.
1.4 Material de 5eferen$ia
-7iste una 'ran $antidad de artG$ulos Lue se o$upan de al'8n aspe$to de jQuery. Al'unos
son e7$elentes pero otrosE fran$amenteE son err*neos. +uando lea un artG$ulo sobre jQueryE
este se'uro Lue se est& abar$ando la misma versi*n de la bibliote$a Lue est& utilizandoE y
resGstase a la tenta$i*n de $opiar y pe'ar el $*di'o U t*mese un tiempo para poder
entenderlo.
A $ontinua$i*n se listan una serie de e7$elentes re$ursos para utilizar durante el
aprendizaje. -l m&s importante de todos es el $*di'o fuente de jQueryE el $ual $ontiene Aen
su formato sin $omprimirB una $ompleta do$umenta$i*n a travFs de $omentarios. 0a
bibliote$a no es una $aja ne'ra U el entendimiento de ella ir& in$rement&ndose
e7ponen$ialmente si la revisa de vez en $uando U y es muy re$omendable Lue la 'uarde en
los favoritos de su nave'ador para tenerla $omo 'uGa de referen$ia.
-l $*di'o fuente de jQuery
)o$umenta$i*n de jQuery
Foro de jQuery
Favoritos en )eli$ious
+anal 65+ VjLuery en Freenode
Capitulo 2
2 < +on$eptos B&si$os de #avaS$ript
2.1 Introduccin
jQuery se en$uentra es$rito en #avaS$riptE un len'uaje de pro'rama$i*n muy ri$o y
e7presivo.
-l $apGtulo est& orientado a personas sin e7perien$ia en el len'uajeE abar$ando $on$eptos
b&si$os y problemas fre$uentes Lue pueden presentarse al trabajar $on el mismo. %or otro
ladoE la se$$i*n puede ser benefi$iosa para Luienes utili$en otros len'uajes de
pro'rama$i*n para entender las pe$uliaridades de #avaS$ript.
Si usted esta interesado en aprender el len'uaje m&s en profundidadE puede leer el libro
#avaS$riptN 3:e Cood %arts es$rito por )ou'las +ro$=ford.
2.2 Sinta7is B&si$a
+omprensi*n de de$lara$ionesE nombres de variablesE espa$ios en blan$oE y otras sinta7is
b&si$as de #avaS$ript.
Declaracin simple de variable
var foo = 'hola mundo';
os espacios en blanco no tienen valor !uera de las comillas
var foo = 'hola mundo';
os par"ntesis indican prioridad
2 ! " #; // es igual a 11, la multiplicacin ocurre primero
2 (! " #); // es igual a 16, por los parntesis, la suma ocurre primero
a tabulacin mejora la lectura del cdigo# pero no posee ning$n signi!icado
especial
var foo = function() $
console.log('hola');
%;
2.! Operadores
2.3.1 Operadores Bsicos
0os operadores b&si$os permiten manipular valores.
Concatenacin
var foo = 'hola';
var &ar = 'mundo';

console.log(foo " ' ' " &ar); // la consola de depuracin muestra 'hola mundo'
%ultiplicacin & divisin
2 !;
2 / !;
'ncrementacin & decrementacin
var i = ';

var j = ""i; // incrementacin previa: j es igual a 2; i es igual a 2
var ( = i""; // incrementacin posterior: es igual a 2; i es igual a !
2.!.2 Opera$iones $on 28meros y +adenas de +ara$teres
-n #avaS$riptE las opera$iones $on n8meros y $adenas de $ara$teres Aen in'lFs strin'sB
pueden o$asionar resultados no esperados.
Suma vs( concatenacin
var foo = ';
var &ar = '2';

console.log(foo " &ar); // error: "a consola de depuracin muestra 12
)or*ar a una cadena de caracteres actuar como un n$mero
var foo = ';
var &ar = '2';

// el constructor '#um$er' o$liga a la cadena comportarse como un n%mero
console.log(foo " )um&er(&ar)); // la consola de depuracin muestra !
-l $onstru$tor 2umberE $uando es llamado $omo una fun$i*n A$omo se muestra en el
ejemploB obli'a a su ar'umento a $omportarse $omo un n8mero. 3ambiFn es posible
utilizar el operador de suma unariaE entre'ando el mismo resultadoN
)or*ar a una cadena de caracteres actuar como un n$mero +utili*ando el
operador de suma unaria,
console.log(foo " "&ar);
2.!.! Operadores 0*'i$os
0os operadores l*'i$os permiten evaluar una serie de operandos utilizando opera$iones
A2) y O5.
-peradores lgicos .ND & -/
var foo = ';
var &ar = *;
var &a+ = 2;

foo ,, &ar; // devuelve 1, el cual es verdadero &true'
&ar ,, foo; // devuelve 1, el cual es verdadero &true'

foo -- &ar; // devuelve (, el cual es falso &false'
foo -- &a+; // devuelve 2, el cual es verdadero &true'
&a+ -- foo; // devuelve 1, el cual es verdadero &true'
-l operador || AO5 l*'i$oB devuelve el valor del primer operandoE si Fste es verdaderoO
$aso $ontrario devuelve el se'undo operando. Si ambos operandos son falsos devuelve
falso AfalseB. -l operador && AA2) l*'i$oB devuelve el valor del primer operando si Fste es
falsoO $aso $ontrario devuelve el se'undo operando. +uando ambos valores son verdaderos
devuelve verdadero AtrueBE sino devuelve falso.
%uede $onsultar la se$$i*n lementos !erdaderos " #alsos para m&s detalles sobre
Lue valores se eval8an $omo true y $uales se eval8an $omo false.
Nota
%uede Lue a ve$es note Lue al'unos desarrolladores utilizan esta l*'i$a en flujos
de $ontrol en lu'ar de utilizar la de$lara$i*n if. %or ejemploN
// reali)ar algo con foo si foo es verdadero
foo -- do.omething(foo);

// esta$lecer $ar igual a $a) si $a) es verdadero;
// caso contrario, esta$lecer a $ar igual al
// valor de create*ar&'
var &ar = &a+ ,, create/ar();
-ste estilo de de$lara$i*n es muy ele'ante y $on$isoO pero puede ser difG$il para leer
Asobretodo para prin$ipiantesB. %or eso se e7plG$itaE para re$ono$erlo $uando este leyendo
$*di'o. Sin embar'o su utiliza$i*n no es re$omendable a menos Lue estF $*modo $on el
$on$epto y su $omportamiento.
2.!.( Operadores de +ompara$i*n
0os operadores de $ompara$i*n permiten $omprobar si determinados valores son
eLuivalentes o idFnti$os.
-peradores de Comparacin
var foo = ';
var &ar = *;
var &a+ = ''';
var &im = 2;

foo == &ar; // devuelve falso &false'
foo 0= &ar; // devuelve verdadero &true'
foo == &a+; // devuelve verdadero &true'; tenga cuidado

foo === &a+; // devuelve falso &false'
foo 0== &a+; // devuelve verdadero &true'
foo === parse1nt(&a+); // devuelve verdadero &true'

foo > &im; // devuelve falso &false'
&im > &a+; // devuelve verdadero &true'
foo <= &a+; // devuelve verdadero &true'
2.( +*di'o +ondi$ional
A ve$es se desea eje$utar un bloLue de $*di'o bajo $iertas $ondi$iones. 0as estru$turas de
$ontrol de flujo U a travFs de la utiliza$i*n de las de$lara$iones if y else permiten
:a$erlo.
Control del !lujo
var foo = true;
var &ar = false;

if (&ar) $
// este cdigo nunca se ejecutar
console.log('hola0');
%

if (&ar) $
// este cdigo no se ejecutar
% else $
if (foo) $
// este cdigo se ejecutar
% else $
// este cdigo se ejecutar si foo + $ar son falsos &false'
%
%
Nota
-n una lGnea sin'ularE $uando se es$ribe una de$lara$i*n ifE las llaves no son
estri$tamente ne$esariasO sin embar'o es re$omendable su utiliza$i*nE ya Lue
:a$e Lue el $*di'o sea mu$:o m&s le'ible.
)ebe tener en $uenta de no definir fun$iones $on el mismo nombre m8ltiples ve$es dentro
de de$lara$ionesif/elseE ya Lue puede obtener resultados no esperados.
2.4.1 Elementos erdaderos ! "alsos
%ara $ontrolar el flujo ade$uadamenteE es importante entender LuF tipos de valores son
HverdaderosI y $uales HfalsosI. A ve$esE al'unos valores pueden pare$er una $osa pero al
final terminan siendo otra.
0alores 1ue devuelven verdadero (true)
'*';
'any string'; // cual,uier cadena
23; // un vector vac-o
$%; // un o$jeto vac-o
'; // cual,uier n%mero distinto a cero
0alores 1ue devuelven falso (false)
*;
''; // una cadena vac-a
NaN; // la varia$le .ava/cript 0not1a1num$er0 &#o es un n%mero'
null; // un valor nulo
undefined; // tenga cuidado 11 indefinido &undefined' puede ser redefinido
2.(.2 9ariables +ondi$ionales /tilizando el Operador 3ernario
A ve$es se desea estable$er el valor de una variable dependiendo de $ierta $ondi$i*n. %ara
:a$erlo se puede utilizar una de$lara$i*n if/elseE sin embar'o en mu$:os $asos es m&s
$onveniente utilizar el operador ternario. W)efini$i*nN -l operador ternario eval8a una
$ondi$i*nO si la $ondi$i*n es verdaderaE devuelve $ierto valorE $aso $ontrario devuelve un
valor diferente.X
El operador ternario
// esta$lecer a foo igual a 1 si $ar es verdadero;
// caso contrario, esta$lecer a foo igual a (
var foo = &ar 4 ' 5 *;
-l operador ternario puede ser utilizado sin devolver un valor a la variableE sin embar'o
este uso 'eneralmente es desaprobado.
2.(.! )e$lara$i*n Sit$:
-n lu'ar de utilizar una serie de de$lara$iones if/else/else if/elseE a ve$es puede ser 8til la
utiliza$i*n de la de$lara$i*n switch. W)efini$i*nN 0a de$lara$i*n $witch eval8a el valor
de una variable o e7presi*nE y eje$uta diferentes bloLues de $*di'o dependiendo de ese
valor.X
2na declaracin S3itch
switch (foo) $

case '&ar'5
alert('el 6alor es &ar');
break;

case '&a+'5
alert('el 6alor es &a+');
break;

default5
alert('de forma predeterminada se ejecutar7 este c8digo');
break;

%
0as de$lara$iones switch son po$o utilizadas en #avaS$riptE debido a Lue el mismo
$omportamiento es posible obtenerlo $reando un objetoE el $ual posee m&s poten$ial ya
Lue es posible reutilizarloE usarlo para realizar pruebasE et$. %or ejemploN
var stuff9o:o = $
'&ar' 5 function() $
alert('el 6alor es &ar');
%;

'&a+' 5 function() $
alert('el 6alor es &a+');
%;

'default' 5 function() $
alert('de forma predeterminada se ejecutar7 este c8digo');
%
%;

if (stuff9o:o2foo3) $
stuff9o:o2foo3();
% else $
stuff9o:o2'default'3();
%
M&s adelante se abar$ar& el $on$epto de objetos.
2., Bu$les
0os bu$les Aen in'lFs loopsB permiten eje$utar un bloLue de $*di'o un determinado
n8mero de ve$es.
4ucles
// muestra en la consola 'intento (', 'intento 1', 222, 'intento 3'
for (var i=*; i<#; i"") $
console.log('intento ' " i);
%
Y2ote Lue en el ejemplo se utiliza la palabra var antes de la variable iE esto :a$e Lue di$:a
variable Luede dentro del Hal$an$eI Aen in'lFs s$opeB del bu$le. M&s adelante en este
$apGtulo se e7aminar& en profundidad el $on$epto de al$an$e.Y
2.#.1 Bucles $tilizando "or
/n bu$le utilizando for se $ompone de $uatro estados y posee la si'uiente estru$turaN
for (2e<presi8n1nicial3; 2condici8n3; 2incremento:e=a><presi8n3)
2cuerpo3
-l estado e7presi*n6ni$ial es eje$utado una sola vezE antes Lue el bu$le $omien$e. Fste
otor'a la oportunidad de preparar o de$larar variables.
-l estado $ondi$i*n es eje$utado antes de $ada repeti$i*nE y retorna un valor Lue de$ide si
el bu$le debe $ontinuar eje$ut&ndose o no. Si el estado $ondi$ional eval8a un valor falso el
bu$le se detiene.
-l estado in$remento)e0a-7presi*n es eje$utado al final de $ada repeti$i*n y otor'a la
oportunidad de $ambiar el estado de importantes variables. %or lo 'eneralE este estado
impli$a la in$rementa$i*n o de$rementa$i*n de un $ontador.
-l $uerpo es el $*di'o a eje$utar en $ada repeti$i*n del bu$le.
2n tpico bucle utili*ando for
for (var i = *; limit = '**; i < limit; i"") $
// 4ste $lo,ue de cdigo ser ejecutado 1(( veces
console.log('?ctualmente en ' " i);
// #ota: el %ltimo registro ,ue se mostrar
// en la consola ser 05ctualmente en 660
%
2.,.2 Bu$les /tilizando ;:ile
/n bu$le utilizando while es similar a una de$lara$i*n $ondi$ional ifE e7$epto Lue el
$uerpo va a $ontinuar eje$ut&ndose :asta Lue la $ondi$i*n a evaluar sea falsa.
while (2condici8n3) 2cuerpo3
2n tpico bucle utili*ando while
var i = *;
while (i < '**) $
// 4ste $lo,ue de cdigo se ejecutar 1(( veces
console.log('?ctualmente en ' " i);
i""; // incrementa la varia$le i
%
%uede notar Lue en el ejemplo se in$rementa el $ontador dentro del $uerpo del bu$leE pero
tambiFn es posible $ombinar la $ondi$i*n y la in$rementa$i*nE $omo se muestra a
$ontinua$i*nN
4ucle utili*ando while con la combinacin de la condicin & la
incrementacin
var i = @';
while (""i < '**) $
// 4ste $lo,ue de cdigo se ejecutar 1(( veces
console.log('?ctualmente en ' " i);
%
Se $omienza en %& y lue'o se utiliza la in$rementa$i*n previa A''iB.
2.,.! Bu$les /tilizando )o<:ile
-ste bu$le es e7a$tamente i'ual Lue el bu$le utilizando while e7$epto Lue el $uerpo es
eje$utado al menos una vez antes Lue la $ondi$i*n sea evaluada.
do 2cuerpo3 while (2condici8n3)
2n bucle utili*ando do-while
do $

// 7ncluso cuando la condicin sea falsa
// el cuerpo del $ucle se ejecutar al menos una ve)2

alert('Aola');

% while (false);
-ste tipo de bu$les son bastantes atGpi$os ya Lue en po$as o$asiones se ne$esita un bu$le
Lue se eje$ute al menos una vez. )e $ualLuier forma debe estar al tanto de ellos.
2.,.( Brea= y +ontinue
/sualmenteE el fin de la eje$u$i*n de un bu$le resultar& $uando la $ondi$i*n no si'a
evaluando un valor verdaderoE sin embar'o tambiFn es posible parar un bu$le utilizando la
de$lara$i*n brea( dentro del $uerpo.
Detener un bucle con brea5
for (var i = *; i < '*; i"") $
if (something) $
break;
%
%
3ambiFn puede su$eder Lue Luiera $ontinuar $on el bu$le sin tener Lue eje$utar m&s
senten$ias del $uerpo del mismo bu$le. -sto puede realizarse utilizando la de$lara$i*n
continue.
Saltar a la siguiente iteracin de un bucle
for (var i = *; i < '*; i"") $

if (something) $
continue;
%

// "a siguiente declaracin ser ejecutada
// si la condicin 'something' no se cumple
console.log('Aola');

%
2.. %alabras 5eservadas
#avaS$ript posee un n8mero de Hpalabras reservadasIE o palabras Lue son espe$iales
dentro del mismo len'uaje. )ebe utilizar estas palabras $uando las ne$esite para su uso
espe$Gfi$o.
abstract
boolean
brea(
b"te
case
catch
char
class
const
continue
debugger
default
delete
do
double
else
enum
e)port
e)tends
final
finall"
float
for
function
goto
if
implements
import
in
instanceof
int
interface
long
native
new
pac(age
private
protected
public
return
short
static
super
switch
s"nchroni*ed
this
throw
throws
transient
tr"
t"peof
var
void
volatile
while
with
2.1 9e$tores
0os ve$tores Aen espa"ol tambiFn llamados matri$es o arre'los y en in'lFs arraysB son
listas de valores $on Gndi$e<$ero Aen in'lFs zero<inde7BE es de$irE Lue el primer elemento del
ve$tor est& en el Gndi$e ?. Zstos son una forma pr&$ti$a de alma$enar un $onjunto de datos
rela$ionados A$omo $adenas de $ara$teresBE aunLue en realidadE un ve$tor puede in$luir
m8ltiples tipos de datosE in$luso otros ve$tores.
2n vector simple
var my?rray = 2 'hola'; 'mundo' 3;
.cceder a los tems del vector a trav"s de su ndice
var my?rray = 2 'hola'; 'mundo'; 'foo'; '&ar' 3;
console.log(my?rray2!3); // muestra en la consola '$ar'
-btener la cantidad de tems del vector
var my?rray = 2 'hola'; 'mundo' 3;
console.log(my?rray.length); // muestra en la consola 2
Cambiar el valor de un tem de un vector
var my?rray = 2 'hola'; 'mundo' 3;
my?rray2'3 = 'changed';
+omo se muestra en el ejemplo H+ambiar el valor de un Gtem de un ve$torI es posible
$ambiar el valor de un Gtem de un ve$torE sin embar'oE por lo 'eneralE no es a$onsejable.
.6adir elementos a un vector
var my?rray = 2 'hola'; 'mundo' 3;
my?rray.push('neB');
7rabajar con vectores
var my?rray = 2 'h'; 'o'; 'l'; 'a' 3;
var my.tring = my?rray.join(''); // 'hola'
var my.plit = my.tring.split(''); // 8 'h', 'o', 'l', 'a' 9
2.4 Objetos
0os objetos son elementos Lue pueden $ontener $ero o m&s $onjuntos de pares de nombres
$laves y valores aso$iados a di$:o objeto. 0os nombres $laves pueden ser $ualLuier palabra
o n8mero v&lido. -l valor puede ser $ualLuier tipo de valorN un n8meroE una $adenaE un
ve$torE una fun$i*nE in$luso otro objeto.
W)efini$i*nN +uando uno de los valores de un objeto es una fun$i*nE Fsta es nombrada
$omo un mFtodo del objeto.X )e lo $ontrarioE se los llama propiedades.
+uriosamenteE en #avaS$riptE $asi todo es un objeto U ve$toresE fun$ionesE n8merosE
in$luso $adenas U y todos poseen propiedades y mFtodos.
Creacin de un 8objeto literal9
var myC&ject = $
sayAello5 function() $
console.log('hola');
%;

my)ame5 'De&ecca'
%;

myC&ject.sayAello(); // se llama al mtodo sa+:ello,
// el cual muestra en la consola 'hola'

console.log(myC&ject.my)ame); // se llama a la propiedad m+#ame,
// la cual muestra en la consola ';e$ecca'
Nota
2otar Lue $uando se $rean objetos literalesE el nombre de la propiedad puede
ser $ualLuier identifi$ador #avaS$riptE una $adena de $ara$teres Aen$errada
entre $omillasB o un n8meroN
var myC&ject = $
6alid1dentifier5 '2!;
'some string'5 E#F;
GGGGG5 HIG
%;
0os objetos literales pueden ser muy 8tiles para la or'aniza$i*n del $*di'oE para m&s
informa$i*n puede leer el artG$ulo Aen in'lFsB /sin' Obje$ts to Or'anize [our +ode por
5ebe$$a Murp:ey.
2.> Fun$iones
0as fun$iones $ontienen bloLues de $*di'o Lue se eje$utaran repetidamente. A las mismas
se le pueden pasar ar'umentosE y op$ionalmente la fun$i*n puede devolver un valor.
0as fun$iones pueden ser $readas de varias formasN
Declaracin de una !uncin
function foo() $ /< hacer algo </ %
Declaracin de una !uncin nombrada
var foo = function() $ /< hacer algo </ %
-s preferible el mFtodo de fun$i*n nombrada debido a al'unas profundas razones tF$ni$as.
6'ualmenteE es probable en$ontrar a los dos mFtodos $uando se revise $*di'o #avaS$ript.
2.%.1 $tilizacin de "unciones
2na !uncin simple
var greet = function(person; greeting) $
var te<t = greeting " '; ' " person;
console.log(te<t);
%;


greet('De&ecca'; 'Aola'); // muestra en la consola ':ola, ;e$ecca'
2na !uncin 1ue devuelve un valor
var greet = function(person; greeting) $
var te<t = greeting " '; ' " person;
return te<t;
%;

console.log(greet('De&ecca';'Aola')); // la funcin devuelve ':ola, ;e$ecca',
// la cual se muestra en la consola
2na !uncin 1ue devuelve otra !uncin
var greet = function(person; greeting) $
var te<t = greeting " '; ' " person;
return function() $ console.log(te<t); %;
%;


var greeting = greet('De&ecca'; 'Aola');
greeting(); // se muestra en la consola ':ola, ;e$ecca'
2.>.2 Fun$iones An*nimas Autoeje$utables
/n patr*n $om8n en #avaS$ript son las fun$iones an*nimas autoeje$utables. -ste patr*n
$onsiste en $rear una e7presi*n de fun$i*n e inmediatamente eje$utarla. -l mismo es muy
8til para $asos en Lue no se desea intervenir espa$ios de nombres 'lobalesE debido a Lue
nin'una variable de$larada dentro de la fun$i*n es visible desde afuera.
)uncin annima autoejecutable
(function()$
var foo = 'Aola mundo';
%)();


console.log(foo); // indefinido &undefined'
2.>.! Fun$iones $omo Ar'umentos
-n #avaS$riptE las fun$iones son H$iudadanos de primera $laseI U pueden ser asi'nadas a
variables o pasadas a otras fun$iones $omo ar'umentos. -n jQueryE pasar fun$iones $omo
ar'umentos es una pr&$ti$a muy $om8n.
:asar una !uncin annima como un argumento
var myJn = function(fn) $
var result = fn();
console.log(result);
%;

myJn(function() $ return 'hola mundo'; %); // muestra en la consola 'hola mundo'
:asar una !uncin nombrada como un argumento
var myJn = function(fn) $
var result = fn();
console.log(result);
%;

var myCtherJn = function() $
return 'hola mundo';
%;

myJn(myCtherJn); // muestra en la consola 'hola mundo'
2.1? )etermina$i*n del 3ipo de 9ariable
#avaS$ript ofre$e una manera de poder $omprobar el HtipoI Aen in'lFs typeB de una
variable. Sin embar'oE el resultado puede ser $onfuso U por ejemploE el tipo de un ve$tor
es Hobje$tI.
%or esoE es una pr&$ti$a $om8n utilizar el operador t"peof $uando se trata de determinar
el tipo de un valor espe$Gfi$o.
Determinar el tipo en di!erentes variables
var myJunction = function() $
console.log('hola');
%;

var myC&ject = $
foo 5 '&ar'
%;

var my?rray = 2 'a'; '&'; 'c' 3;

var my.tring = 'hola';

var my)um&er = !;

typeof myJunction; // devuelve 'function'
typeof myC&ject; // devuelve 'o$ject'
typeof my?rray; // devuelve 'o$ject' 11 tenga cuidado
typeof my.tring; // devuelve 'string'
typeof my)um&er; // devuelve 'num$er'

typeof null; // devuelve 'o$ject' 11 tenga cuidado


if (my?rray.push -- my?rray.slice -- my?rray.join) $
// pro$a$lemente sea un vector
// &este estilo es llamado, en ingls, 0duc t+ping0'
%

if (C&ject.prototype.to.tring.call(my?rray) === '2o&ject ?rray3') $
// definitivamente es un vector;
// esta es considerada la forma ms ro$usta
// de determinar si un valor es un vector2
%
jQuery ofre$e mFtodos para ayudar a determinar el tipo de un determinado valor. -stos
mFtodos ser&n vistos m&s adelante.
2.11 0a palabra $lave this
-n #avaS$riptE asG $omo en la mayorGa de los len'uajes de pro'rama$i*n orientados a
objetosE this es una palabra $lave espe$ial Lue :a$e referen$ia al objeto en donde el
mFtodo est& siendo invo$ado. -l valor de this es determinado utilizando una serie de
simples pasosN
1. Si la fun$i*n es invo$ada utilizando Fun$tion.$all o Fun$tion.applyE this tendr& el valor
del primer ar'umento pasado al mFtodo. Si el ar'umento es nulo AnullB o indefinido
AundefinedBE this :ar& referen$ia el objeto 'lobal Ael objeto windowBO
2. Si la fun$i*n a invo$ar es $reada utilizando Fun$tion.bindE this ser& el primer ar'umento
Lue es pasado a la fun$i*n en el momento en Lue se la $reaO
3. Si la fun$i*n es invo$ada $omo un mFtodo de un objetoE this referen$iar& a di$:o objetoO
4. )e lo $ontrarioE si la fun$i*n es invo$ada $omo una fun$i*n independienteE no unida a
al'8n objetoE thisreferen$iar& al objeto 'lobal.
2na !uncin invocada utili*ando )unction(call
var myC&ject = $
sayAello 5 function() $
console.log('Aola; mi nom&re es ' " this.my)ame);
%;

my)ame 5 'De&ecca'
%;

var secondC&ject = $
my)ame 5 'Kolin'
%;

myC&ject.sayAello(); // registra ':ola, mi nom$re es ;e$ecca'
myC&ject.sayAello.call(secondC&ject); // registra ':ola, mi nom$re es =olin'
2na !uncin creada utili*ando )unction(bind
var my)ame = 'el o&jeto glo&al';

sayAello = function () $
console.log('Aola; mi nom&re es ' " this.my)ame);
%;

myC&ject = $
my)ame 5 'De&ecca'
%;

var myC&jectAello = sayAello.&ind(myC&ject);

sayAello(); // registra ':ola, mi nom$re es el o$jeto glo$al'
myC&jectAello(); // registra ':ola, mi nom$re es ;e$ecca'
2na !uncin vinculada a un objeto
var my)ame = 'el o&jeto glo&al';

sayAello = function() $
console.log('Aola; mi nom&re es ' " this.my)ame);
%;

myC&ject = $
my)ame 5 'De&ecca'
%;

secondC&ject = $
my)ame 5 'Kolin'
%;

myC&ject.sayAello = sayAello;
secondC&ject.sayAello = sayAello;

sayAello(); // registra ':ola, mi nom$re es el o$jeto glo$al'
myC&ject.sayAello(); // registra ':ola, mi nom$re es ;e$ecca'
secondC&ject.sayAello(); // registra ':ola, mi nom$re es =olin'
Nota
-n al'unas oportunidadesE $uando se invo$a una fun$i*n Lue se en$uentra
dentro de un espa$io de nombres Aen in'lFs namespa$eB amplioE puede ser una
tenta$i*n 'uardar la referen$ia a la fun$i*n a$tual en una variable m&s $orta y
a$$esible. Sin embar'oE es importante no realizarlo en instan$ias de mFtodosE ya
Lue puede llevar a la eje$u$i*n de $*di'o in$orre$to. %or ejemploN
var my)amespace = $
myC&ject5 $
sayAello5 function() $
console.log('Aola; mi nom&re es ' " this.my)ame);
%;

my)ame5 'De&ecca'
%
%;

var hello = my)amespace.myC&ject.sayAello;

hello(); // registra ':ola, mi nom$re es undefined'
%ara Lue no o$urran estos erroresE es ne$esario :a$er referen$ia al objeto en donde el
mFtodo es invo$adoN
var my)amespace = $
myC&ject 5 $
sayAello 5 function() $
console.log('Aola; mi nom&re es ' " this.my)ame);
%;

my)ame 5 'De&ecca'
%
%;

var o&j = my)amespace.myC&ject;

o&j.sayAello(); // registra ':ola, mi nom$re es ;e$ecca'
2.12 Al$an$e
-l Hal$an$eI Aen in'lFs s$opeB se refiere a las variables Lue est&n disponibles en un bloLue
de $*di'o en un tiempo determinado. 0a falta de $omprensi*n de este $on$epto puede
llevar a una frustrante e7perien$ia de depura$i*n.
+uando una variable es de$larada dentro de una fun$i*n utilizando la palabra $lave varE
Fsta 8ni$amente esta disponible para el $*di'o dentro de la fun$i*n U todo el $*di'o fuera
de di$:a fun$i*n no puede a$$eder a la variable. %or otro ladoE las fun$iones definidas
dentro de la fun$i*n podr&n a$$eder a la variable de$larada.
0as variables Lue son de$laradas dentro de la fun$i*n sin la palabra $lave var no Luedan
dentro del &mbito de la misma fun$i*n U #avaS$ript bus$ar& el lu'ar en donde la variable
fue previamente de$laradaE y en $aso de no :aber sido de$laradaE es definida dentro del
al$an$e 'lobalE lo $ual puede o$asionar $onse$uen$ias inesperadasO
)unciones tienen acceso a variables de!inidas dentro del mismo alcance
var foo = 'hola';

var sayAello = function() $
console.log(foo);
%;

sayAello(); // muestra en la consola 'hola'
console.log(foo); // tam$in muestra en la consola 'hola'
El cdigo de a!uera no tiene acceso a la variable de!inida dentro de la !uncin
var sayAello = function() $
var foo = 'hola';
console.log(foo);
%;

sayAello(); // muestra en la consola 'hola'
console.log(foo); // no muestra nada en la consola
0ariables con nombres iguales pero valores di!erentes pueden existir en
di!erentes alcances
var foo = 'mundo';

var sayAello = function() $
var foo = 'hola';
console.log(foo);
%;

sayAello(); // muestra en la consola 'hola'
console.log(foo); // muestra en la consola 'mundo'
as !unciones pueden 8ver9 los cambios en las variables antes de 1ue la
!uncin sea de!inida
var myJunction = function() $
var foo = 'hola';

var myJn = function() $
console.log(foo);
%;

foo = 'mundo';

return myJn;
%;

var f = myJunction();
f(); // registra 'mundo' 11 error
.lcance
// una funcin annima autoejecuta$le
(function() $
var &a+ = ';
var &im = function() $ alert(&a+); %;
&ar = function() $ alert(&a+); %;
%)();

console.log(&a+); // "a consola no muestra nada, +a ,ue $a)
// esta definida dentro del alcance de la funcin annima

&ar(); // $ar esta definido fuera de la funcin annima
// +a ,ue fue declarada sin la pala$ra clave var; adems,
// como fue definida dentro del mismo alcance ,ue $a),
// se puede consultar el valor de $a) a pesar ,ue
// sta este definida dentro del alcance de la funcin annima

&im(); // $im no esta definida para ser accesi$le fuera de la funcin annima,
// por lo cual se mostrar un error
2.1! +lausuras
0as $lausuras Aen in'lFs $losuresB son una e7tensi*n del $on$epto de al$an$e As$opeB U
fun$iones Lue tienen a$$eso a las variables Lue est&n disponibles dentro del &mbito en
donde se $re* la fun$i*n. Si este $on$epto es $onfusoE no debe preo$uparseN se entiende
mejor a travFs de ejemplos.
-n el ejemplo 2.(1 se muestra la forma en Lue fun$iones tienen a$$eso para $ambiar el
valor de las variables. -l mismo $omportamiento su$ede en fun$iones $readas dentro de
bu$les U la fun$i*n HobservaI el $ambio en la variableE in$luso despuFs de Lue la fun$i*n
sea definidaE resultando Lue en todos los $li$=s aparez$a una ventana de alerta mostrando
el valor ,.
;Cmo establecer el valor de i<
/< esto no se comporta como se desea; </
/< cada clic mostrar una ventana de alerta con el valor > </
for (var i=*; i<#; i"") $
L('<p>hacer clic(</p>').append9o('&ody').clic((function() $
alert(i);
%);
%
Establecer el valor de i utili*ando una clausura
/< solucin: ?clausurar@ el valor de i dentro de createAunction </
var createJunction = function(i) $
return function() $
alert(i);
%;
%;

for (var i = *; i < #; i"") $
L('<p>hacer clic(</p>').append9o('&ody').clic((createJunction(i));
%
0as $lausuras tambiFn pueden ser utilizadas para resolver problemas $on la palabra $lave
thisE la $ual es 8ni$a en $ada al$an$e.
2tili*ar una clausura para acceder simult=neamente a instancias de objetos
internos & externos(
var outerC&j = $
my)ame5 'e<terno';
outerJunction5 function() $

// provee una referencia al mismo o$jeto outerB$j
// para utili)ar dentro de innerAunction
var self = this;

var innerC&j = $
my)ame5 'interno';
innerJunction5 function() $
console.log(self.my)ame; this.my)ame); // registra 'eCterno interno'
%
%;

innerC&j.innerJunction();

console.log(this.my)ame); // registra 'eCterno'
%
%;

outerC&j.outerJunction();
-ste me$anismo puede ser 8til $uando trabaje $on fun$iones de devolu$i*n de llamadas
Aen in'lFs $allba$=sB. Sin embar'oE en estos $asosE es preferible Lue utili$e Fun$tion.bind
ya Lue evitar& $ualLuier sobre$ar'a aso$iada $on el al$an$e As$opeB.
Capitulo >
! < +on$eptos B&si$os de jQuery
3.1 &'document(.read!'(
2o es posible intera$tuar de forma se'ura $on el $ontenido de una p&'ina :asta Lue el
do$umento no se en$uentre preparado para su manipula$i*n. jQuery permite dete$tar
di$:o estado a travFs de la de$lara$i*n$(document).read"() de forma tal Lue el bloLue
se eje$utar& s*lo una vez Lue la p&'ina este disponible.
El blo1ue ?+document,(read&+,
L(document).ready(function() $
console.log('el documento est7 preparado');
%);
-7iste una forma abreviada para $(document).read"() la $ual podr& en$ontrar al'unas
ve$esO sin embar'oE es re$omendable no utilizarla en $aso Lue este es$ribiendo $*di'o para
'ente Lue no $ono$e jQuery.
)orma abreviada para ?+document,(read&+,
L(function() $
console.log('el documento est7 preparado');
%);
Adem&s es posible pasarle a $(document).read"() una fun$i*n nombrada en lu'ar de
una an*nimaN
:asar una !uncin nombrada en lugar de una !uncin annima
function readyJn() $
// cdigo a ejecutar cuando el documento este listo
%


L(document).ready(readyJn);
!.2 Sele$$i*n de -lementos
-l $on$epto m&s b&si$o de jQuery es el de Hsele$$ionar al'unos elementos y realizar
a$$iones $on ellosI. 0a bibliote$a soporta 'ran parte de los sele$tores +SS! y varios m&s no
estandarizados. -n:ttpN//api.jLuery.$om/$ate'ory/sele$tors/ se puede en$ontrar una
$ompleta referen$ia sobre los sele$tores de la bibliote$a.
A $ontinua$i*n se muestran al'unas tF$ni$as $omunes para la sele$$i*n de elementosN
Seleccin de elementos en base a su 'D
L('Mmy1d'); // notar ,ue los 7Ds de$en ser %nicos por pgina
Seleccin de elementos en base al nombre de clase
L('di6.myKlass'); // si se especifica el tipo de elemento,
// se mejora el rendimiento de la seleccin
Seleccin de elementos por su atributo
L('input2name=firstNname3'); // tenga cuidado, ,ue puede ser mu+ lento
Seleccin de elementos en !orma de selector CSS
L('Mcontents ul.people li');
:seudo@selectores
L('a.e<ternal5first'); // selecciona el primer elemento EaF
// con la clase 'eCternal'
L('tr5odd'); // selecciona todos los elementos EtrF
// impares de una ta$la
L('MmyJorm 5input'); // selecciona todos los elementos del tipo input
// dentro del formulario Gm+Aorm
L('di656isi&le'); // selecciona todos los divs visi$les
L('di65gt(2)'); // selecciona todos los divs eCcepto los tres primeros
L('di65animated'); // selecciona todos los divs actualmente animados
Nota
+uando se utilizan los pseudo<sele$tores +visible y +hiddenE jQuery
$omprueba la visibilidad a$tual del elemento pero no si Fste posee asi'nados los
estilos +SS visibilit" o displa" U en otras palabrasE verifi$a si el alto y
an$:o fGsi$o del elemento es mayor a $ero. Sin embar'oE esta $omproba$i*n no
fun$iona $on los elementos ,tr-O en este $asoE jQuery $omprueba si se est&
apli$ando el estilodispla" y va a $onsiderar al elemento $omo o$ulto si posee
asi'nado el valor none. Adem&sE los elementos Lue a8n no fueron a"adidos al
)OM ser&n tratados $omo o$ultosE in$luso si tienen apli$ados estilos indi$ando
Lue deben ser visibles A-n la se$$i*n Manipula$i*n de este manualE se e7pli$a
$omo $rear y a"adir elementos al )OMB.
+omo referen$iaE este es el fra'mento de $*di'o Lue utiliza jQuery para determinar $uando
un elemento es visible o no. Se in$orporaron los $omentarios para Lue Luede m&s $laro su
entendimientoN
jOuery.e<pr.filters.hidden = function( elem ) $
var Bidth = elem.offsetPidth; height = elem.offsetAeight;
s(ip = elem.node)ame.to=oBerKase() === QtrQ;

// Hel elemento posee alto (, ancho ( + no es un EtrFI
return Bidth === * -- height === * -- 0s(ip 4

// entonces de$e estar oculto &hidden'
true 5

// pero si posee ancho + alto
// + no es un EtrF
Bidth > * -- height > * -- 0s(ip 4

// entonces de$e estar visi$le
false 5

// si nos encontramos a,u-, es por,ue el elemento posee ancho
// + alto, pero adems es un EtrF,
// entonces se verifica el valor del estilo displa+
// aplicado a travs de =//
// para decidir si est oculto o no
jOuery.curK..(elem; QdisplayQ) === QnoneQ;
%;

jOuery.e<pr.filters.6isi&le = function( elem ) $
return 0jOuery.e<pr.filters.hidden( elem );
%;
Eleccin de Selectores
0a ele$$i*n de buenos sele$tores es un punto importante $uando se desea mejorar el
rendimiento del $*di'o. /na peLue"a espe$ifi$idad U por ejemploE in$luir el tipo de
elemento A$omo divB $uando se realiza una sele$$i*n por el nombre de $lase U puede
ayudar bastante. %or esoE es re$omendable darle al'unas HpistasI a jQuery sobre en Lue
lu'ar del do$umento puede en$ontrar lo Lue desea sele$$ionar. %or otro ladoE demasiada
espe$ifi$idad puede ser perjudi$ial. /n sele$tor $omo .mi/abla thead tr
th.especial es un e7$esoE lo mejor serGa utilizar.mi/abla th.especial.
jQuery ofre$e mu$:os sele$tores basados en atributosE Lue permiten realizar sele$$iones
basadas en el $ontenido de los atributos utilizando simplifi$a$iones de e7presiones
re'ulares.
// encontrar todos los EaF cu+o atri$uto rel terminan en 0thinger0
L(Qa2relL='thinger'3Q);
-stos tipos de sele$tores pueden resultar 8tiles pero tambiFn ser muy lentos. +uando sea
posibleE es re$omendable realizar la sele$$i*n utilizando 6)sE nombres de $lases y nombres
de etiLuetas.
Si desea $ono$er m&s sobre este asuntoE %aul 6ris: realiz* una 'ran presenta$i*n sobre
mejoras de rendimiento en #avaS$ript Aen in'lesBE la $ual posee varias diapositivas
$entradas en sele$tores.
3.2.1 )omprobar *elecciones
/na vez realizada la sele$$i*n de los elementosE Luerr& $ono$er si di$:a sele$$i*n entre'*
al'8n resultado. %ara elloE pueda Lue es$riba al'o asGN
if (L('di6.foo')) $ ... %
Sin embar'o esta forma no fun$ionar&. +uando se realiza una sele$$i*n utilizando $()E
siempre es devuelto un objetoE y si se lo eval8aE Fste siempre devolver& true. 6n$luso si la
sele$$i*n no $ontiene nin'8n elementoE el $*di'o dentro del bloLue if se eje$utar&.
-n lu'ar de utilizar el $*di'o mostradoE lo Lue se debe :a$er es pre'untar por la $antidad
de elementos Lue posee la sele$$i*n Lue se eje$ut*. -sto es posible realizarlo utilizando la
propiedad #avaS$ript length. Si la respuesta es ?E la $ondi$i*n evaluar& falsoE $aso
$ontrario Am&s de ? elementosBE la $ondi$i*n ser& verdadera.
Evaluar si una seleccin posee elementos
if (L('di6.foo').length) $ ... %
!.2.2 Cuardar Sele$$iones
+ada vez Lue se :a$e una sele$$i*nE una 'ran $antidad de $*di'o es eje$utado. jQuery no
'uarda el resultado por si soloE por lo tantoE si va a realizar una sele$$i*n Lue lue'o se :ar&
de nuevoE deber& salvar la sele$$i*n en una variable.
Auardar selecciones en una variable
var Ldi6s = L('di6');
Nota
-n el ejemplo HCuardar sele$$iones en una variableIE la variable $omienza $on el
si'no de d*lar. +ontrariamente a otros len'uajes de pro'rama$i*nE en
#avaS$ript este si'no no posee nin'8n si'nifi$ado espe$ial U es solamente otro
$ar&$ter. Sin embar'o aLuG se utilizar& para indi$ar Lue di$:a variable posee un
objeto jQuery. -sta pr&$ti$a U una espe$ie de 2ota$i*n M8n'ara U es solo una
$onven$i*n y no es obli'atoria.
/na vez Lue la sele$$i*n es 'uardada en la variableE se la puede utilizar en $onjunto $on los
mFtodos de jQuery y el resultado ser& i'ual Lue utilizando la sele$$i*n ori'inal.
Nota
0a sele$$i*n obtiene s*lo los elementos Lue est&n en la p&'ina $uando se realiz*
di$:a a$$i*n. Si lue'o se a"aden elementos al do$umentoE ser& ne$esario repetir
la sele$$i*n o a"adir los elementos nuevos a la sele$$i*n 'uardada en la variable.
-n otras palabrasE las sele$$iones 'uardadas no se a$tualizan Hm&'i$amenteI
$uando el )OM se modifi$a.
!.2.! 5efinamiento y Filtrado de Sele$$iones
A ve$esE puede obtener una sele$$i*n Lue $ontiene m&s de lo Lue ne$esitaO en este $asoE es
ne$esario refinar di$:a sele$$i*n. jQuery ofre$e varios mFtodos para poder obtener
e7a$tamente lo Lue desea.
/e!inamiento de selecciones
L('di6.foo').has('p'); // el elemento div2foo contiene elementos EpF
L('h'').not('.&ar'); // el elemento h1 no posse la clase '$ar'
L('ul li').filter('.current'); // un item de una lista desordenada
// ,ue posse la clase 'current'
L('ul li').first(); // el primer item de una lista desordenada
L('ul li').eq(#); // el seCto item de una lista desordenada
!.2.( Sele$$i*n de -lementos de un Formulario
jQuery ofre$e varios pseudo<sele$tores Lue ayudan a en$ontrar elementos dentro de los
formulariosE Fstos son espe$ialmente 8tiles ya Lue dependiendo de los estados de $ada
elemento o su tipoE puede ser difG$il distin'uirlos utilizando sele$tores +SS est&ndar.
Nbutton
Sele$$iona elementos ,button- y $on el atributo t"pe01button1
N$:e$=bo7
Sele$$iona elementos ,input- $on el atributo t"pe01chec(bo)1
N$:e$=ed
Sele$$iona elementos ,input- del tipo chec(bo) sele$$ionados
Ndisabled
Sele$$iona elementos del formulario Lue est&n des:abitados
Nenabled
Sele$$iona elementos del formulario Lue est&n :abilitados
Nfile
Sele$$iona elementos ,input- $on el atributo t"pe01file1
Nima'e
Sele$$iona elementos ,input- $on el atributo t"pe01image1
Ninput
Sele$$iona elementos ,input-E ,te)tarea- y ,select-
Npassord
Sele$$iona elementos ,input- $on el atributo t"pe01password1
Nradio
Sele$$iona elementos ,input- $on el atributo t"pe01radio1
Nreset
Sele$$iona elementos ,input- $on el atributo t"pe01reset1
Nsele$ted
Sele$$iona elementos ,options- Lue est&n sele$$ionados
Nsubmit
Sele$$iona elementos ,input- $on el atributo t"pe01submit1
Nte7t
Sele$$iona elementos ,input- $on el atributo t"pe01te)t1
2tili*ando pseudo@selectores en elementos de !ormularios
L('MmyJorm 5input'); // o$tiene todos los elementos inputs
// dentro del formulario Gm+Aorm
!.! 3rabajar $on Sele$$iones
/na vez realizada la sele$$i*n de los elementosE es posible utilizarlos en $onjunto $on
diferentes mFtodos. FstosE 'eneralmenteE son de dos tiposN obtenedores Aen in'lFs 'ettersB
y estable$edores Aen in'lFs settersB. 0os mFtodos obtenedores devuelven una propiedad del
elemento sele$$ionadoO mientras Lue los mFtodos estable$edores fijan una propiedad a
todos los elementos sele$$ionados.
3.3.1 Encadenamiento
Si en una sele$$i*n se realiza una llamada a un mFtodoE y Fste devuelve un objeto jQueryE
es posible se'uir un Hen$adenadoI de mFtodos en el objeto.
Encadenamiento
L('Mcontent').find('h!').eq(2).html('nue6o te<to para el tercer elemento h!');
%or otro ladoE si se est& es$ribiendo un en$adenamiento de mFtodos Lue in$luyen mu$:os
pasosE es posible es$ribirlos lGnea por lGneaE :a$iendo Lue el $*di'o luz$a m&s a'radable
para leer.
)ormateo de cdigo encadenado
L('Mcontent')
.find('h!')
.eq(2)
.html('nue6o te<to para el tercer elemento h!');
Si desea volver a la sele$$i*n ori'inal en el medio del en$adenadoE jQuery ofre$e el mFtodo
$.fn.end para poder :a$erlo.
/establecer la seleccin original utili*ando el m"todo $.fn.end
L('Mcontent')
.find('h!')
.eq(2)
.html('nue6o te<to para el tercer elemento h!')
.end() // reesta$lece la seleccin a todos los elementos h! en Gcontent
.eq(*)
.html('nue6o te<to para el primer elemento h!');
Nota
-l en$adenamiento es muy poderoso y es una $ara$terGsti$a Lue mu$:as
bibliote$as #avaS$ript :an adoptado desde Lue jQuery se :izo popular. Sin
embar'oE debe ser utilizado $on $uidado. /n en$adenamiento de mFtodos
e7tensivo pueden :a$er un $*di'o e7tremadamente difG$il de modifi$ar y
depurar. 2o e7iste una re'la Lue indiLue Lue tan lar'o o $orto debe ser el
en$adenado U pero es re$omendable Lue ten'a en $uenta este $onsejo.
!.!.2 Obtenedores ACettersB D -stable$edores ASettersB
jQuery Hsobre$ar'aI sus mFtodosE en otras palabrasE el mFtodo para estable$er un valor
posee el mismo nombre Lue el mFtodo para obtener un valor. +uando un mFtodo es
utilizado para estable$er un valorE es llamado mFtodo estable$edor Aen in'lFs setterB. -n
$ambioE $uando un mFtodo es utilizado para obtener Ao leerB un valorE es llamado
obtenedor Aen in'lFs 'etterB.
El m"todo $.fn.html utili*ado como establecedor
L('h'').html('hello Borld');
El m"todo html utili*ado como obtenedor
L('h'').html();
0os mFtodos estable$edores devuelven un objeto jQueryE permitiendo $ontinuar $on la
llamada de m&s mFtodos en la misma sele$$i*nE mientras Lue los mFtodos obtenedores
devuelven el valor por el $ual se $onsult*E pero no permiten se'uir llamando a m&s
mFtodos en di$:o valor.
!.( +SSE -stilosE D )imensiones
jQuery in$luye una manera 8til de obtener y estable$er propiedades +SS a los elementos.
Nota
0as propiedades +SS Lue in$luyen $omo separador un 'ui*n del medioE en
#avaS$ript deben ser transformadas a su estilo +amel+ase. %or ejemploE $uando
se la utiliza $omo propiedad de un mFtodoE el estilo +SS font%si*e deber& ser
e7presado $omo font$i*e. Sin embar'oE esta re'la no es apli$ada $uando se
pasa el nombre de la propiedad +SS al mFtodo $.fn.css U en este $asoE los
dos formatos Aen+amel+ase o $on el 'ui*n del medioB fun$ionar&n.
-btener propiedades CSS
L('h'').css('font.i+e'); // devuelve una cadena de caracteres como 016pC0
L('h'').css('font@si+e'); // tam$in funciona
Establecer propiedades CSS
L('h'').css('font.i+e'; ''**p<'); // esta$lece una propiedad individual =//
L('h'').css($
'font.i+e' 5 ''**p<';
'color' 5 'red'
%); // esta$lece m%ltiples propiedades =//
2otar Lue el estilo del ar'umento utilizado en la se'unda lGnea del ejemplo U es un objeto
Lue $ontiene m8ltiples propiedades. -sta es una forma $om8n de pasar m8ltiples
ar'umentos a una fun$i*nE y mu$:os mFtodos estable$edores de la bibliote$a a$eptan
objetos para fijar varias propiedades de una sola vez.
A partir de la versi*n 1.. de la bibliote$aE utilizando $.fn.css tambiFn es posible
estable$er valores relativos en las propiedades +SS de un elemento determinadoN
Establecer valores CSS relativos
L('h'').css($
'font.i+e' 5 '"='#p<'; // suma 1>pC al tamaJo original del elemento
'padding9op' 5 '"=2*p<' // suma 2(pC al padding superior original del elemento
%);
3.4.1 $tilizar )lases para Aplicar Estilos )**
%ara obtener valores de los estilos apli$ados a un elementoE el mFtodo $.fn.css es muy
8tilE sin embar'oE su utiliza$i*n $omo mFtodo estable$edor se debe evitar Aya LueE para
apli$ar estilos a un elementoE se puede :a$er dire$tamente desde +SSB. -n su lu'arE lo
idealE es es$ribir re'las +SS Lue se apliLuen a $lases Lue des$riban los diferentes estados
visuales de los elementos y lue'o $ambiar la $lase del elemento para apli$ar el estilo Lue se
desea mostrar.
7rabajar con clases
var Lh' = L('h'');

Lh'.addKlass('&ig');
Lh'.remo6eKlass('&ig');
Lh'.toggleKlass('&ig');

if (Lh'.hasKlass('&ig')) $ ... %
0as $lases tambiFn pueden ser 8tiles para 'uardar informa$i*n del estado de un elementoE
por ejemploE para indi$ar Lue un elemento fue sele$$ionado.
!.(.2 )imensiones
jQuery ofre$e una variedad de mFtodos para obtener y modifi$ar valores de dimensiones y
posi$i*n de un elemento.
-l $*di'o mostrado en el ejemplo HMFtodos b&si$os sobre )imensionesI es solo un breve
resumen de las fun$ionalidades rela$iones a dimensiones en jQueryO para un $ompleto
detalle puede $onsultar:ttpN//api.jLuery.$om/$ate'ory/dimensions/.
%"todos b=sicos sobre Dimensiones
L('h'').Bidth('#*p<'); // esta$lece el ancho de todos los elementos :1
L('h'').Bidth(); // o$tiene el ancho del primer elemento :1

L('h'').height('#*p<'); // esta$lece el alto de todos los elementos :1
L('h'').height(); // o$tiene el alto del primer elemento :1

L('h'').position(); // devuelve un o$jeto conteniendo
// informacin so$re la posicin
// del primer elemento relativo al
// 0offset0 &posicin' de su elemento padre
!., Atributos
0os atributos de los elementos M3M0 Lue $onforman una apli$a$i*n pueden $ontener
informa$i*n 8tilE por eso es importante poder estable$er y obtener esa informa$i*n.
-l mFtodo $.fn.attr a$t8a tanto $omo mFtodo estable$edor $omo obtenedor. Adem&sE
al i'ual Lue el mFtodo$.fn.cssE $uando se lo utiliza $omo mFtodo estable$edorE puede
a$eptar un $onjunto de palabra $lave<valor o un objeto $onteniendo m&s $onjuntos.
Establecer atributos
L('a').attr('href'; 'allRyArefs?re9he.ame)oB.html');
L('a').attr($
'title' 5 'all titles are the same too';
'href' 5 'something)eB.html'
%);
-n el ejemploE el objeto pasado $omo ar'umento est& es$rito en varias lGneas. +omo se
e7pli$* anteriormenteE los espa$ios en blan$o no importan en #avaS$riptE por lo $ualE es
libre de utilizarlos para :a$er el $*di'o m&s le'ible. -n entornos de produ$$i*nE se pueden
utilizar :erramientas de minifi$a$i*nE los $uales Luitan los espa$ios en blan$o Aentre otras
$osasB y $omprimen el ar$:ivo final.
-btener atributos
L('a').attr('href'); // devuelve el atri$uto href perteneciente
// al primer elemento EaF del documento
!.. 5e$orrer el )OM
/na vez obtenida la sele$$i*nE es posible en$ontrar otros elementos utilizando a la misma
sele$$i*n.
-n :ttpN//api.jLuery.$om/$ate'ory/traversin'/ puede en$ontrar una $ompleta
do$umenta$i*n sobre los mFtodos de re$orrido de )OM Aen in'lFs traversin'B Lue posee
jQuery.
Nota
)ebe ser $uidadoso en re$orrer lar'as distan$ias en un do$umento U re$orridos
$omplejos obli'an Lue la estru$tura del do$umento sea siempre la mismaE al'o
Lue es difG$il de 'arantizar. /no <o dos< pasos para el re$orrido esta bienE pero
'eneralmente :ay Lue evitar atravesar desde un $ontenedor a otro.
%overse a trav"s del D-% utili*ando m"todos de recorrido
L('h'').ne<t('p'); // seleccionar el inmediato + prCimo
// elemento EpF con respecto a :1
L('di656isi&le').parent(); // seleccionar el elemento contenedor
// a un div visi$le
L('input2name=firstNname3').closest('form'); // seleccionar el elemento
// EformF ms cercano a un input
L('Mmy=ist').children(); // seleccionar todos los elementos
// hijos de Gm+"ist
L('li.selected').si&lings(); // seleccionar todos los items
// hermanos del elemento EliF
3ambiFn es posible intera$tuar $on la sele$$i*n utilizando el mFtodo $.fn.each. )i$:o
mFtodo intera$t8a $on todos los elementos obtenidos en la sele$$i*n y eje$uta una fun$i*n
por $ada uno. 0a fun$i*n re$ibe $omo ar'umento el Gndi$e del elemento a$tual y al mismo
elemento. )e forma predeterminadaE dentro de la fun$i*nE se puede :a$er referen$ia al
elemento )OM a travFs de la de$lara$i*n this.
'nteractuar en una seleccin
L('Mmy=ist li').each(function(id<; el) $
console.log(
'>l elemento ' " id< "
'contiene el siguiente A9R=5 ' "
L(el).html()
);
%);
!.1 Manipula$i*n de -lementos
/na vez realizada la sele$$i*n de los elementos Lue desea utilizarE Hla diversi*n $omienzaI.
-s posible $ambiarE moverE remover y dupli$ar elementos. 3ambiFn $rear nuevos a travFs
de una sinta7is simple.
0a do$umenta$i*n $ompleta sobre los mFtodos de manipula$i*n puede en$ontrarla en la
se$$i*n ManipulationN:ttpN//api.jLuery.$om/$ate'ory/manipulation/.
3.+.1 Obtener ! Establecer In,ormacin en Elementos
-7isten mu$:as formas por las $uales de puede modifi$ar un elemento. -ntre las tareas
m&s $omunes est&n las de $ambiar el M3M0 interno o al'8n atributo del mismo. %ara este
tipo de tareasE jQuery ofre$e mFtodos simplesE fun$ionales en todos los nave'adores
modernos. 6n$luso es posible obtener informa$i*n sobre los elementos utilizando los
mismos mFtodos pero en su forma de mFtodo obtenedor.
Nota
5ealizar $ambios en los elementosE es un trabajo trivialE pero :ay debe re$ordar
Lue el $ambio afe$tar& atodos los elementos en la sele$$i*nE por lo LueE si desea
modifi$ar un s*lo elementoE tiene Lue estar se'uro de espe$ifi$arlo en la
sele$$i*n antes de llamar al mFtodo estable$edor.
Nota
+uando los mFtodos a$t8an $omo obtenedoresE por lo 'eneralE solamente
trabajan $on el primer elemento de la sele$$i*n. Adem&s no devuelven un objeto
jQueryE por lo $ual no es posible en$adenar m&s mFtodos en el mismo. /na
e7$ep$i*n es el mFtodo $.fn.te)tE el $ual permite obtener el te7to de los
elementos de la sele$$i*n.
@.fn.:tml
Obtiene o estable$e el $ontenido M3M0 de un elemento.
@.fn.te7t
Obtiene o estable$e el $ontenido en te7to del elementoO en $aso se pasarle $omo
ar'umento $*di'o M3M0E este es despojado.
@.fn.attr
Obtiene o estable$e el valor de un determinado atributo.
@.fn.idt:
Obtiene o estable$e el an$:o en pi7eles del primer elemento de la sele$$i*n $omo un
entero.
@.fn.:ei':t
Obtiene o estable$e el alto en pi7eles del primer elemento de la sele$$i*n $omo un
entero.
@.fn.position
Obtiene un objeto $on informa$i*n sobre la posi$i*n del primer elemento de la
sele$$i*nE relativo al primer elemento padre posi$ionado. -ste mFtodo es solo
obtenedor.
@.fn.val
Obtiene o estable$e el valor AvalueB en elementos de formularios.
Cambiar el B7% de un elemento
L('Mmy:i6 p5first')
.html(')ue6o <strong>primer</strong> p7rrafo');
!.1.2 MoverE +opiar y 5emover -lementos
-7isten varias maneras para mover elementos a travFs del )OMO las $uales se pueden
separar en dos enfoLuesN
Luerer $olo$ar el/los elementos sele$$ionados de forma relativa a otro elementoO
Luerer $olo$ar un elemento relativo a el/los elementos sele$$ionados.
%or ejemploE jQuery provee los mFtodos $.fn.insert2fter y $.fn.after. -l
mFtodo$.fn.insert2fter $olo$a a el/los elementos sele$$ionados despuFs del
elemento Lue se :aya pasado $omo ar'umentoO mientras Lue el mFtodo $.fn.after
$olo$a al elemento pasado $omo ar'umento despuFs del elemento sele$$ionado. Otros
mFtodos tambiFn si'uen este patr*nN $.fn.insert3efore y $.fn.beforeO
$.fn.append/o y $.fn.appendO y $.fn.prepend/o y $.fn.prepend.
0a utiliza$i*n de uno u otro mFtodo depender& de los elementos Lue ten'a sele$$ionados y
el tipo de referen$ia Lue se Luiera 'uardar $on respe$to al elemento Lue se esta moviendo.
%over elementos utili*ando di!erentes en!o1ues
// hacer ,ue el primer item de la lista sea el %ltimo
var Lli = L('Mmy=ist li5first').append9o('Mmy=ist');

// otro enfo,ue para el mismo pro$lema
L('Mmy=ist').append(L('Mmy=ist li5first'));

// de$e tener en cuenta ,ue no ha+ forma de acceder a la
// lista de items ,ue se ha movido, +a ,ue devuelve
// la lista en s-
3.7.2.1 Clonar Elementos
+uando se utiliza un mFtodo $omo $.fn.append/oE lo Lue se est& :a$iendo es mover al
elementoO pero a ve$es en lu'ar de esoE se ne$esita mover un dupli$ado del mismo
elemento. -n este $asoE es posible utilizar el mFtodo$.fn.clone.
-btener una copia del elemento
// copiar el primer elemento de la lista + moverlo al final de la misma
L('Mmy=ist li5first').clone().append9o('Mmy=ist');
Nota
Si se ne$esita $opiar informa$i*n y eventos rela$ionados al elementoE se debe
pasar true $omo ar'umento de $.fn.clone.
!.1.2.2 5emover elementos
-7isten dos formas de remover elementos de una p&'inaN /tilizando $.fn.remove o
$.fn.detach. +uando desee remover de forma permanente al elementoE utilize el
mFtodo $.fn.remove. %or otro ladoE el mFtodo @.fn.deta$: tambiFn remueve el
elementoE pero mantiene la informa$i*n y eventos aso$iados al mismoE siendo 8til en el
$aso Lue ne$esite reinsertar el elemento en el do$umento.
Nota
-l mFtodo $.fn.detach es muy 8til $uando se esta manipulando de forma
severa un elementoE ya Lue es posible eliminar al elementoE trabajarlo en el
$*di'o y lue'o restaurarlo en la p&'ina nuevamente. -sta forma tiene $omo
benefi$io no to$ar el )OM mientras se est& modifi$ando la informa$i*n y
eventos del elemento.
%or otro ladoE si se desea mantener al elemento pero se ne$esita eliminar su $ontenidoE es
posible utiliza el mFtodo$.fn.empt"E el $ual Hva$iar&I el $ontenido M3M0 del elemento.
!.1.! +rear 2uevos -lementos
jQuery provee una forma f&$il y ele'ante para $rear nuevos elementos a travFs del mismo
mFtodo $() Lue se utiliza para realizar sele$$iones.
Crear nuevos elementos
L('<p>Sn nue6o p7rrafo</p>');
L('<li class=QneBQ>nue6o item de la lista</li>');
Crear un nuevo elemento con atributos utili*ando un objeto
L('<a/>'; $
html 5 'Sn <strong>nue6o</strong> enlace';
'class' 5 'neB';
href 5 'foo.html'
%);
2ote Lue en el objeto Lue se pasa $omo ar'umentoE la propiedad $lass est& entre $omillasE
mientras Lue la propiedad :ref y :tml no lo est&n. %or lo 'eneralE los nombres de
propiedades no deben estar entre $omillasE e7$epto en el $aso Lue se utili$e $omo nombre
una palabra reservada A$omo es el $aso de $lassB.
+uando se $rea un elementoE Fste no es a"adido inmediatamente a la p&'inaE sino Lue se
debe :a$erlo en $onjunto $on un mFtodo.
Crear un nuevo elemento en la p=gina
var Lmy)eB>lement = L('<p>)ue6o elemento</p>');
Lmy)eB>lement.append9o('Mcontent');

Lmy)eB>lement.insert?fter('ul5last'); // eliminar al elemento EpF
// eCistente en Gcontent
L('ul').last().after(Lmy)eB>lement.clone()); // clonar al elemento EpF
// para tener las dos versiones
-stri$tamente :ablandoE no es ne$esario 'uardar al elemento $reado en una variable U es
posible llamar al mFtodo para a"adir el elemento dire$tamente despuFs de @AB. Sin
embar'oE la mayorGa de las ve$es se desear& :a$er referen$ia al elemento a"adidoE por lo
$ualE si se 'uarda en una variable no es ne$esario sele$$ionarlo despuFs.
Crear & a6adir al mismo tiempo un elemento a la p=gina
L('ul').append('<li>item de la lista</li>');
Nota
0a sinta7is para a"adir nuevos elementos a la p&'ina es muy f&$il de utilizarE
pero es tentador olvidar Lue :ay un $osto enorme de rendimiento al a're'ar
elementos al )OM de forma repetida. Si esta a"adiendo mu$:os elementos al
mismo $ontenedorE en lu'ar de a"adir $ada elemento uno por vezE lo mejor es
$on$atenar todo el M3M0 en una 8ni$a $adena de $ara$teres para lue'o
ane7arla al $ontenedor. /na posible solu$i*n es utilizar un ve$tor Lue posea
todos los elementosE lue'o reunirlos utilizando join y finalmente ane7arla.
var my1tems = 23; Lmy=ist = L('Mmy=ist');

for (var i=*; i<'**; i"") $
my1tems.push('<li>item ' " i " '</li>');
%

Lmy=ist.append(my1tems.join(''));
!.1.( Manipula$i*n de Atributos
0as $apa$idades para la manipula$i*n de atributos Lue ofre$e la bibliote$a son e7tensos. 0a
realiza$i*n de $ambios b&si$os son simplesE sin embar'o el mFtodo $.fn.attr permite
manipula$iones m&s $omplejas.
%anipular un simple atributo
L('Mmy:i6 a5first').attr('href'; 'neB:estination.html');
%anipular m$ltiples atributos
L('Mmy:i6 a5first').attr($
href 5 'neB:estination.html';
rel 5 'super@special'
%);
2tili*ar una !uncin para determinar el valor del nuevo atributo
L('Mmy:i6 a5first').attr($
rel 5 'super@special';
href 5 function(id<; href) $
return '/neB/' " href;
%
%);

L('Mmy:i6 a5first').attr('href'; function(id<; href) $
return '/neB/' " href;
%);
!.4 -jer$i$ios
3.-.1 *elecciones
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/sandbo).js o trabaje dire$tamente $on Firebu'
para $umplir los si'uientes puntosN
1. Sele$$ionar todos los elementos div Lue poseen la $lase HmoduleI.
2. -spe$ifi$ar tres sele$$iones Lue puedan sele$$ionar el ter$er Gtem de la lista desordenada
Vmy0ist. J+u&l es el mejor para utilizarK J%orLuFK
3. Sele$$ionar el elemento label del elemento input utilizando un sele$tor de atributo.
4. Averi'uar $uantos elementos en la p&'ina est&n o$ultos AayudaN .lengthB.
#. Averi'uar $uantas im&'enes en la p&'ina poseen el atributo alt.
.. Sele$$ionar todas las filas impares del $uerpo de la tabla.
!.4.2 5e$orrer el )OM
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/sandbo).js o trabaje dire$tamente $on Firebu'
para $umplir los si'uientes puntosN
1. Sele$$ionar todas las im&'enes en la p&'inaO re'istrar en la $onsola el atributo alt de $ada
ima'en.
2. Sele$$ionar el elemento inputE lue'o diri'irse :a$ia el formulario y a"adirle una $lase al
mismo.
!. Sele$$ionar el Gtem Lue posee la $lase H$urrentI dentro de la lista Vmy0ist y remover di$:a
$lase en el elementoO lue'o a"adir la $lase H$urrentI al si'uiente Gtem de la lista.
4. Sele$$ionar el elemento select dentro de Vspe$ialsO lue'o diri'irse :a$ia el bot*n
submit.
,. Sele$$ionar el primer Gtem de la lista en el elemento Vslides:oO a"adirle la $lase H$urrentI
al mismo y lue'o a"adir la $lase HdisabledI a los elementos :ermanos.
!.4.! Manipula$i*n
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/sandbo).js o trabaje dire$tamente $on Firebu'
para $umplir los si'uientes puntosN
1. A"adir , nuevos Gtems al final de la lista desordenada Vmy0ist. AyudaN
for (var i = *; i<#; i"") $ ... %
2. 5emover los Gtems impares de la lista.
3. A"adir otro elemento h4 y otro p&rrafo al 8ltimo div.module.
4. A"adir otra op$i*n al elemento selectO darle a la op$i*n a"adida el valor H;ednesdayI.
#. A"adir un nuevo div.module a la p&'ina despuFs del 8ltimoO lue'o a"adir una $opia de
una de las im&'enes e7istentes dentro del nuevo div.
Capitulo C
( < -l n8$leo de jQuery
4.1 $ .s $()
Masta a:oraE se :a tratado $ompletamente $on mFtodos Lue se llaman desde el objeto
jQuery. %or ejemploN
L('h'').remo6e();
)i$:os mFtodos son parte del espa$io de nombres Aen in'lFs namespa$eB $.fnE o del
prototipo Aen in'lFsprototypeB de jQueryE y son $onsiderados $omo mFtodos del objeto
jQuery.
Sin embar'oE e7isten mFtodos Lue son parte del espa$io de nombres de @ y se $onsideran
$omo mFtodos del n8$leo de jQuery.
-stas distin$iones pueden ser bastantes $onfusas para usuarios nuevos. %ara evitar la
$onfusi*nE debe re$ordar estos dos puntosN
los mFtodos utilizados en sele$$iones se en$uentran dentro del espa$io de nombres $.fnE y
autom&ti$amente re$iben y devuelven una sele$$i*n en sGO
mFtodos en el espa$io de nombres $ son 'eneralmente mFtodos para diferentes utilidadesE
no trabajan $on sele$$ionesE no se les pasa nin'8n ar'umento y el valor Lue devuelven
puede variar.
-7isten al'unos $asos en donde mFtodos del objeto y del n8$leo poseen los mismos
nombresE $omo su$ede $on$.each y $.fn.each. -n estos $asosE debe ser $uidadoso de
leer bien la do$umenta$i*n para saber Lue objeto utilizar $orre$tamente.
(.2 MFtodos /tilitarios
jQuery ofre$e varios mFtodos utilitarios dentro del espa$io de nombres $. -stos mFtodos
son de 'ran ayuda para llevar a $abo tareas rutinarias de pro'rama$i*n. A $ontinua$i*n se
muestran al'unos ejemplosE para una $ompleta do$umenta$i*n sobre ellosE visite
:ttpN//api.jLuery.$om/$ate'ory/utilities/.
@.trim
5emueve los espa$ios en blan$o del prin$ipio y final.
L.trim(' 6arios espacios en &lanco ');
// devuelve 'varios espacios en $lanco'
@.ea$:
6ntera$t8a en ve$tores y objetos.
L.each(2 'foo'; '&ar'; '&a+' 3; function(id<; 6al) $
console.log('elemento ' " id< " 'es ' " 6al);
%);

L.each($ foo 5 '&ar'; &a+ 5 '&im' %; function((; 6) $
console.log(( " ' 5 ' " 6);
%);
Nota
+omo se dijo antesE e7iste un mFtodo llamado $.fn.eachE el $ual intera$t8a en
una sele$$i*n de elementos.
@.inArray
)evuelve el Gndi$e de un valor en un ve$torE o <1 si el valor no se en$uentra en el ve$tor.
var my?rray = 2 '; 2; !; # 3;

if (L.in?rray(E; my?rray) 0== @') $
console.log('6alor encontrado');
%
@.e7tend
+ambia la propiedades del primer objeto utilizando las propiedades de los subse$uentes
objetos.
var firstC&ject = $ foo 5 '&ar'; a 5 '&' %;
var secondC&ject = $ foo 5 '&a+' %;

var neBC&ject = L.e<tend(firstC&ject; secondC&ject);
console.log(firstC&ject.foo); // '$a)'
console.log(neBC&ject.foo); // '$a)'
Si no se desea $ambiar las propiedades de nin'uno de los objetos Lue se utilizan en
$.e)tendE se debe in$luir un objeto va$Go $omo primer ar'umento.
var firstC&ject = $ foo 5 '&ar'; a 5 '&' %;
var secondC&ject = $ foo 5 '&a+' %;

var neBC&ject = L.e<tend($%; firstC&ject; secondC&ject);
console.log(firstC&ject.foo); // '$ar'
console.log(neBC&ject.foo); // '$a)'
@.pro7y
)evuelve una fun$i*n Lue siempre se eje$utar& en el al$an$e As$opeB provisto U en otras
palabrasE estable$e el si'nifi$ado de t:is Ain$luido dentro de la fun$i*nB $omo el se'undo
ar'umento.
var myJunction = function() $ console.log(this); %;
var myC&ject = $ foo 5 '&ar' %;

myJunction(); // devuelve el o$jeto KindoK

var myTro<yJunction = L.pro<y(myJunction; myC&ject);
myTro<yJunction(); // devuelve el o$jeto m+B$ject
Si se posee un objeto $on mFtodosE es posible pasar di$:o objeto y el nombre de un mFtodo
para devolver una fun$i*n Lue siempre se eje$uta en el al$an$e de di$:o objeto.
var myC&ject = $
myJn 5 function() $
console.log(this);
%
%;

L('Mfoo').clic((myC&ject.myJn); // registra el elemento DBL Gfoo
L('Mfoo').clic((L.pro<y(myC&ject; 'myJn')); // registra m+B$ject
(.! +omproba$i*n de 3ipos
+omo se men$ion* en el $apGtulo H+on$eptos B&si$os de #avaS$riptIE jQuery ofre$e varios
mFtodos 8tiles para determinar el tipo de un valor espe$Gfi$o.
Comprobar el tipo de un determinado valor
var myUalue = 2'; 2; !3;

// Mtili)ar el operador t+peof de .ava/cript para compro$ar tipos primitivos
typeof myUalue == 'string'; // falso &false'
typeof myUalue == 'num&er'; // falso &false'
typeof myUalue == 'undefined'; // falso &false'
typeof myUalue == '&oolean'; // falso &false'

// Mtili)ar el operador de igualdad estricta para compro$ar valores nulos &null'
myUalue === null; // falso &false'

// Mtili)ar los mtodos jNuer+ para compro$ar tipos no primitivos
jOuery.isJunction(myUalue); // falso &false'
jOuery.isTlainC&ject(myUalue); // falso &false'
jOuery.is?rray(myUalue); // verdadero &true'
jOuery.is)umeric('F); // verdadero &true'2 #o disponi$le en versiones inferiores a jNuer+ 12O
(.( -l MFtodo )ata
A menudo en$ontrar& Lue e7iste informa$i*n a$er$a de un elemento Lue ne$esita 'uardar.
-n #avaS$ript es posible :a$erlo a"adiendo propiedades al )OM del elementoE pero esta
pr&$ti$a $onlleva enfrentarse a pFrdidas de memoria Aen in'lFs memory lea=sB en al'unos
nave'adores. jQuery ofre$e una manera sen$illa para poder 'uardar informa$i*n
rela$ionada a un elementoE y la misma bibliote$a se o$upa de manejar los problemas Lue
pueden sur'ir por falta de memoria.
Auardar & recuperar in!ormacin relacionada a un elemento
L('Mmy:i6').data('(ey)ame'; $ foo 5 '&ar' %);
L('Mmy:i6').data('(ey)ame'); // P foo : '$ar' Q
A travFs del mFtodo $.fn.data es posible 'uardar $ualLuier tipo de informa$i*n sobre un
elemento. -s difG$il e7a'erar la importan$ia de este $on$epto $uando se est& desarrollando
una apli$a$i*n $ompleja.
%or ejemploE si desea estable$er una rela$i*n entre el Gtem de una lista y el div Lue :ay
dentro de este GtemE es posible :a$erlo $ada vez Lue se intera$t8a $on el GtemE pero una
mejor solu$i*n es :a$erlo una sola vezE 'uardando un puntero al div utilizando el mFtodo
$.fn.dataN
Establecer una relacin entre elementos utili*ando el m"todo $.fn.data
L('Mmy=ist li').each(function() $
var Lli = L(this); Ldi6 = Lli.find('di6.content');
Lli.data('content:i6'; Ldi6);
%);

// luego, no se de$e volver a $uscar al div;
// es posi$le leerlo desde la informacin asociada al item de la lista
var Lfirst=i = L('Mmy=ist li5first');
Lfirst=i.data('content:i6').html('nue6o contenido');
Adem&s es posible pasarle al mFtodo un objeto $onteniendo uno o m&s pares de $onjuntos
palabra $lave<valor.
A partir de la versi*n 1., de la bibliote$aE jQuery permite utilizar al mFtodo $.fn.data
para obtener la informa$i*n aso$iada a un elemento Lue posea el atributo M3M0, data%
5N
Elementos con el atributo data-*
<a id='foo' data@foo='&a+' href='M'>Joo</a>

<a id='foo&ar' data@foo@&ar='fol' href='M'>Joo /ar</a>
-btener los valores asociados a los atributos data-* con $.fn.data
// o$tiene el valor del atri$uto data1foo
// utili)ando el mtodo R2fn2data
console.log(L('Mfoo').data('foo')); // registra '$a)'

// o$tiene el valor del segundo elemento
console.log(L('Mfoo&ar').data('foo/ar')); // registra 'fol'
Nota
A partir de la versi*n 1.. de la bibliote$aE para obtener el valor del atributo
data%foo%bar del se'undo elementoE el ar'umento en $.fn.data se debe
pasar en estilo +amel+ase.
Nota
%ara m&s informa$i*n sobre el atributo M3M0, data%5 visite
:ttpN//.!.or'/35/:tml,/'lobal<attributes.:tmlVembeddin'<$ustom<non<
visible<data<it:<t:e<data<attributes.
(., )ete$$i*n de 2ave'adores y +ara$terGsti$as
M&s all& Lue jQuery elimine la mayorGa de las pe$uliaridades de #avaS$ript entre $ada
nave'adorE e7isten o$asiones en Lue se ne$esita eje$utar $*di'o en un nave'ador
espe$Gfi$o.
%ara este tipo de situa$ionesE jQuery ofre$e el objeto $.support y $.browser Aeste
8ltimo en desusoB. /na $ompleta do$umenta$i*n sobre estos objetos puede en$ontrarla en
:ttpN//api.jLuery.$om/jQuery.support/ y:ttpN//api.jLuery.$om/jQuery.broser/
-l objetivo de $.support es determinar LuF $ara$terGsti$as soporta el nave'ador eb.
-l objeto $.browser permite dete$tar el tipo de nave'ador y su versi*n. )i$:o objeto est&
en desuso AaunLue en el $orto plazo no est& planifi$ada su elimina$i*n del n8$leo de la
bibliote$aB y se re$omienda utilizar al objeto$.support para estos prop*sitos.
(.. -vitar +onfli$tos $on Otras Bibliote$as #avaS$ript
Si esta utilizando jQuery en $onjunto $on otras bibliote$as #avaS$riptE las $uales tambiFn
utilizan la variable $E pueden lle'ar a o$urrir una serie de errores. %ara poder
solu$ionarlosE es ne$esario poner a jQuery en su modo Hno<$onfli$toI. -sto se debe realizar
inmediatamente despuFs Lue jQuery se $ar'ue en la p&'ina y antes del $*di'o Lue se va a
eje$utar.
+uando se pone a jQuery en modo Hno<$onfli$toIE la bibliote$a ofre$e la op$i*n de asi'nar
un nombre para reemplazar a la variable $.
:oner a jDuer& en modo no@con!licto
<script src=Qprototype.jsQ></script> // la &i&lioteca prototype
// tam&iVn utili+a L
<script src=Qjquery.jsQ></script> // se carga j,uer+
// en la pgina
<script>var Lj = jOuery.noKonflict();</script> // se iniciali+a
// el modo Qno@conflictoQ
3ambiFn es posible se'uir utilizando $ $onteniendo el $*di'o en una fun$i*n an*nima
autoeje$utable. Zste es un patr*n est&ndar para la $rea$i*n de e7tensiones para la
bibliote$aE ya Lue $ Lueda en$errada dentro del al$an$e de la misma fun$i*n an*nima.
2tili*ar ? dentro de una !uncin annima autoejecutable
<script src=Qprototype.jsQ></script>
<script src=Qjquery.jsQ></script>
<script>
jOuery.noKonflict();

(function(L) $
// el cdigo va a,u-, pudiendo utili)ar R
%)(jOuery);
</script>
Capitulo E
, < -ventos
#.1 Introduccin
jQuery provee mFtodos para aso$iar $ontroladores de eventos Aen in'lFs event :andlersB a
sele$tores. +uando un evento o$urreE la fun$i*n provista es eje$utada. )entro de la
fun$i*nE la palabra $lave this :a$e referen$ia al elemento en Lue el evento o$urre.
%ara m&s detalles sobre los eventos en jQueryE puede $onsultar
:ttpN//api.jLuery.$om/$ate'ory/events/.
0a fun$i*n del $ontrolador de eventos puede re$ibir un objeto. -ste objeto puede ser
utilizado para determinar la naturaleza del evento oE por ejemploE prevenir el
$omportamiento predeterminado de Fste. %ara m&s detalles sobre el objeto del eventoE
visite :ttpN//api.jLuery.$om/$ate'ory/events/event<obje$t/.
,.2 9in$ular -ventos a -lementos
jQuery ofre$e mFtodos para la mayorGa de los eventos U entre ellos $.fn.clic(E
$.fn.focusE $.fn.blurE$.fn.changeE et$. -stos 8ltimos son formas redu$idas del
mFtodo $.fn.on de jQuery A$.fn.bind en versiones anteriores a jQuery 1.1B. -l mFtodo
$.fn.on es 8til para vin$ular Aen in'lFs bindin'B la misma fun$i*n de $ontrolador a
m8ltiples eventosE para $uando se desea proveer informa$i*n al $ontrolador de eventoE
$uando se est& trabajando $on eventos personalizados o $uando se desea pasar un objeto a
m8ltiples eventos y $ontroladores.
0incular un evento utili*ando un m"todo reducido
L('p').clic((function() $
console.log('clic(');
%);
0incular un evento utili*ando el m"todo $.fn.on
L('p').on('clic('; function() $
console.log('clic(');
%);
0incular un evento utili*ando el m"todo $.fn.on con in!ormacin asociada
L('input').on(
'clic( &lur'; // es posi$le vincular m%ltiples eventos al elemento
$ foo 5 '&ar' %; // se de$e pasar la informacin asociada como argumento

function(e6entC&ject) $
console.log(e6entC&ject.type; e6entC&ject.data);
// registra el tipo de evento + la informacin asociada P foo : '$ar' Q
%
);
#.2.1 incular E.entos para Ejecutar una .ez
A ve$es puede ne$esitar Lue un $ontrolador parti$ular se eje$ute solo una vez U y despuFs
de esoE ne$esite Lue nin'uno m&s se eje$uteE o Lue se eje$ute otro diferente. %ara este
prop*sito jQuery provee el mFtodo $.fn.one.
Cambiar controladores utili*ando el m"todo $.fn.one
L('p').one('clic('; function() $
console.log('.e clic(e8 al elemento por primera 6e+');
L(this).clic((function() $ console.log('.e ha clic(eado nue6amente'); %);
%);
-l mFtodo $.fn.one es 8til para situa$iones en Lue ne$esita eje$utar $ierto $*di'o la
primera vez Lue o$urre un evento en un elementoE pero no en los eventos su$esivos.
,.2.2 )esvin$ular -ventos
%ara desvin$ular Aen in'les unbindB un $ontrolador de eventoE puede utilizar el mFtodo
$.fn.off pas&ndole el tipo de evento a des$one$tar. Si se pas* $omo adjunto al evento
una fun$i*n nombradaE es posible aislar la des$one7i*n de di$:a fun$i*n pas&ndola $omo
se'undo ar'umento.
Desvincular todos los controladores del evento clic5 en una seleccin
L('p').off('clic(');
Desvincular un controlador particular del evento clic5
var foo = function() $ console.log('foo'); %;
var &ar = function() $ console.log('&ar'); %;

L('p').on('clic('; foo).on('clic('; &ar);
L('p').off('clic('; &ar); // foo esta atado a%n al evento clic
,.2.! -spa$ios de 2ombres para -ventos
+uando se esta desarrollando apli$a$iones $omplejas o e7tensiones de jQueryE puede ser
8til utilizar espa$ios de nombres para los eventosE y de esta forma evitar Lue se desvin$ulen
eventos $uando no lo desea.
.signar espacios de nombres a eventos
L('p').on('clic(.my)amespace'; function() $ /< 222 </ %);
L('p').off('clic(.my)amespace');
L('p').off('.my)amespace'); // desvincula todos los eventos con
// el espacio de nom$re 'm+#amespace'
,.2.( 9in$ula$i*n de M8ltiples -ventos
Muy a menudoE elementos en una apli$a$i*n estar&n vin$ulados a m8ltiples eventosE $ada
uno $on una fun$i*n diferente. -n estos $asosE es posible pasar un objeto dentro de
$.fn.on $on uno o m&s pares de nombres $laves/valores. +ada $lave ser& el nombre del
evento mientras Lue $ada valor ser& la fun$i*n a eje$utar $uando o$urra el evento.
0incular m$ltiples eventos a un elemento
L('p').on($
'clic('5 function() $
console.log('clic(eado');
%;
'mouseo6er'5 function() $
console.log('so&repasado');
%
%);
,.! -l Objeto del -vento
+omo se men$iona en la introdu$$i*nE la fun$i*n $ontroladora de eventos re$ibe un objeto
del eventoE el $ual $ontiene varios mFtodos y propiedades. -l objeto es $om8nmente
utilizado para prevenir la a$$i*n predeterminada del evento a travFs del mFtodo
prevent)efault. Sin embar'oE tambiFn $ontiene varias propiedades y mFtodos 8tilesN
pa'eRE pa'e[
0a posi$i*n del puntero del rat*n en el momento Lue el evento o$urri*E relativo a las
zonas superiores e izLuierda de la p&'ina.
type
-l tipo de evento Apor ejemplo H$li$=IB.
:i$:
-l bot*n o te$la presionada.
data
Al'una informa$i*n pasada $uando el evento es eje$utado.
tar'et
-l elemento )OM Lue ini$ializ* el evento.
prevent)efaultAB
+an$ela la a$$i*n predeterminada del evento Apor ejemploN se'uir un enla$eB.
stop%ropa'ationAB
)etiene la propa'a$i*n del evento sobre otros elementos.
%or otro ladoE la fun$i*n $ontroladora tambiFn tiene a$$eso al elemento )OM Lue
ini$ializ* el evento a travFs de la palabra $lave this. %ara $onvertir a di$:o elemento )OM
en un objeto jQuery Ay poder utilizar los mFtodos de la bibliote$aB es ne$esario es$ribir $
(this)E $omo se muestra a $ontinua$i*nN
var Lthis = L(this);
Cancelar 1ue al hacer clic5 en un enlace# "ste se siga
L('a').clic((function(e) $
var Lthis = L(this);
if (Lthis.attr('href').match('e6il')) $
e.pre6ent:efault();
Lthis.addKlass('e6il');
%
%);
,.( -je$u$i*n autom&ti$a de +ontroladores de -ventos
A travFs del mFtodo $.fn.triggerE jQuery provee una manera de disparar $ontroladores
de eventos sobre al'8n elemento sin reLuerir la a$$i*n del usuario. Si bien este mFtodo
tiene sus usosE no deberGa ser utilizado para simplemente llamar a una fun$i*n Lue pueda
ser eje$utada $on un $li$= del usuario. -n su lu'arE deberGa 'uardar la fun$i*n Lue se
ne$esita llamar en una variableE y lue'o pasar el nombre de la variable $uando realiza el
vin$ulo Abindin'B. )e esta formaE podr& llamar a la fun$i*n $uando lo desee en lu'ar de
eje$utar $.fn.trigger.
Disparar un controlador de eventos de la !orma correcta
var foo = function(e) $
if (e) $
console.log(e);
% else $
console.log('esta ejecucci8n no pro6ino desde un e6ento');
%
%;


L('p').clic((foo);

foo(); // en lugar de reali)ar R&'p''2trigger&'clic''
,., 6n$rementar el 5endimiento $on la )ele'a$i*n de -ventos
+uando trabaje $on jQueryE fre$uentemente a"adir& nuevos elementos a la p&'inaE y
$uando lo :a'aE ne$esitar& vin$ular eventos a di$:os elementos. -n lu'ar de repetir la tarea
$ada vez Lue se a"ade un elementoE es posible utilizar la dele'a$i*n de eventos para
:a$erlo. +on ellaE podr& enlazar un evento a un elemento $ontenedorE y lue'oE $uando el
evento o$urraE podr& ver en Lue elemento su$ede.
0a dele'a$i*n de eventos posee al'unos benefi$iosE in$luso si no se tiene pensando a"adir
m&s elementos a la p&'ina. -l tiempo reLuerido para enlazar $ontroladores de eventos a
$ientos de elementos no es un trabajo trivialO si posee un 'ran $onjunto de elementosE
deberGa $onsiderar utilizar la dele'a$i*n de eventos a un elemento $ontenedor.
Nota
A partir de la versi*n 1.(.2E se introdujo $.fn.delegateE sin embar'o a partir
de la versi*n 1.1 es preferible utilizar el evento $.fn.on para la dele'a$i*n de
eventos.
Delegar un evento utili*ando $.fn.on
L('MmySnordered=ist').on('clic('; 'li'; function(e) $
var Lmy=ist1tem = L(this);
// 222
%);
Delegar un evento utili*ando $.fn.delegate
L('MmySnordered=ist').delegate('li'; 'clic('; function(e) $
var Lmy=ist1tem = L(this);
// 222
%);
#.#.1 /es.incular E.entos /ele0ados
Si ne$esita remover eventos dele'adosE no puede :a$erlo simplemente desvin$ul&ndolos.
%ara esoE utili$e el mFtodo $.fn.off para eventos $one$tados $on $.fn.onE y
$.fn.undelegate para eventos $one$tados $on$.fn.delegate. Al i'ual Lue $uando se
realiza un vin$uloE op$ionalmenteE se puede pasar el nombre de una fun$i*n vin$ulada.
Desvincular eventos delegados
L('MmySnordered=ist').off('clic('; 'li');
L('MmySnordered=ist').undelegate('li'; 'clic(');
,.. Fun$iones Au7iliares de -ventos
jQuery ofre$e dos fun$iones au7iliares para el trabajo $on eventosN
#.1.1 $.fn.hover
-l mFtodo $.fn.hover permite pasar una o dos fun$iones Lue se eje$utar&n $uando los
eventos mouseenter ymouseleave o$urran en el elemento sele$$ionado. Si se pasa una
sola fun$i*nE est& ser& eje$utada en ambos eventosO en $ambio si se pasan dosE la primera
ser& eje$utada $uando o$urra el evento mouseenterE mientras Lue la se'unda ser&
eje$utada $uando o$urra mouseleave.
Nota
A partir de la versi*n 1.( de jQueryE el mFtodo reLuiere obli'atoriamente dos
fun$iones.
a !uncin auxiliar hover
L('Mmenu li').ho6er(function() $
L(this).toggleKlass('ho6er');
%);
,...2 $.fn.toggle
Al i'ual Lue el mFtodo anteriorE $.fn.toggle re$ibe dos o m&s fun$ionesO $ada vez Lue
un evento o$urreE la fun$i*n si'uiente en la lista se eje$utar&. CeneralmenteE
$.fn.toggle es utilizada $on solo dos fun$iones. -n $aso Lue utiliza m&s de dos
fun$ionesE ten'a $uidadoE ya Lue puede ser difi$ultar la depura$i*n del $*di'o.
a !uncin auxiliar toggle
L('p.e<pander').toggle(
function() $
L(this).pre6().addKlass('open');
%;
function() $
L(this).pre6().remo6eKlass('open');
%
);
,.1 -jer$i$ios
#.+.1 )rear una 2*u0erencia3 para una )aja de In0reso de 4e5to
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejeri$io
utilizando el ar$:ivo/ejercicios/js/input6int.js o trabaje dire$tamente $on
Firebu'. 0a tarea a realizar es utilizar el te7to del elemento label y apli$ar una Hsu'eren$iaI
en la $aja de in'reso de te7to. 0os pasos :a se'uir son los si'uientesN
1. -stable$er el valor del elemento input i'ual al valor del elemento label.
2. A"adir la $lase H:intI al elemento input.
3. 5emover el elemento label.
4. 9in$ular un evento fo$us en el input para remover el te7to de su'eren$ia y la $lase H:intI.
#. 9in$ular un evento blur en el input para restaurar el te7to de su'eren$ia y la $lase H:intI en
$aso Lue no se :aya in'resado al'8n te7to.
JQuF otras $onsidera$iones debe $onsiderar si se desea apli$ar esta fun$ionalidad a un sitio
realK
,.1.2 A"adir una 2ave'a$i*n por %esta"as
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejeri$io
utilizando el ar$:ivo/ejercicios/js/tabs.js o trabaje dire$tamente $on Firebu'. 0a
tarea a realizar es $rear una nave'a$i*n por pesta"as para los dos elementos div.module.
0os pasos :a se'uir son los si'uientesN
1. O$ultar todos los elementos div.module.
2. +rear una lista desordenada antes del primer div.module para utilizar $omo pesta"as.
3. 6ntera$tuar $on $ada div utilizando $.fn.each. %or $ada unoE utilizar el te7to del
elemento :2 $omo el te7to para el Gtem de la lista desordenada.
4. 9in$ular un evento $li$= a $ada Gtem de la lista de forma LueN
muestre el div $orrespondiente y o$ulte el otroO
a"ada la $lase H$urrentI al Gtem sele$$ionadoO
remueva la $lase H$urrentI del otro Gtem de la lista.
,. FinalmenteE mostrar la primera pesta"a.
Capitulo F
. < -fe$tos
1.1 Introduccin
+on jQueryE a're'ar efe$tos a una p&'ina es muy f&$il. -stos efe$tos poseen una
$onfi'ura$i*n predeterminada pero tambiFn es posible proveerles par&metros
personalizados. Adem&s es posible $rear anima$iones parti$ulares estable$iendo valores de
propiedades +SS.
%ara una $ompleta do$umenta$i*n sobre los diferentes tipos de efe$tos puede visitar la
se$$i*n effectsN:ttpN//api.jLuery.$om/$ate'ory/effe$ts/.
..2 -fe$tos 6n$orporados en la Bibliote$a
0os efe$tos m&s utilizado ya vienen in$orporados dentro de la bibliote$a en forma de
mFtodosN
@.fn.s:o
Muestra el elemento sele$$ionado.
@.fn.:ide
O$ulta el elemento sele$$ionado.
@.fn.fade6n
)e forma animadaE $ambia la opa$idad del elemento sele$$ionado al 1??\.
@.fn.fadeOut
)e forma animadaE $ambia la opa$idad del elemento sele$$ionado al ?
@.fn.slide)on
Muestra el elemento sele$$ionado $on un movimiento de deslizamiento verti$al.
@.fn.slide/p
O$ulta el elemento sele$$ionado $on un movimiento de deslizamiento verti$al.
@.fn.slide3o''le
Muestra o o$ulta el elemento sele$$ionado $on un movimiento de deslizamiento
verti$alE dependiendo si a$tualmente el elemento est& visible o no.
2so b=sico de un e!ecto incorporado
L('h'').shoB();
1.2.1 )ambiar la /uracin de los E,ectos
+on la e7$ep$i*n de $.fn.show y $.fn.hideE todos los mFtodos tienen una dura$i*n
predeterminada de la anima$i*n en (??ms. -ste valor es posible $ambiarlo.
Con!igurar la duracin de un e!ecto
L('h'').fade1n(!**); // desvanecimiento en !((ms
L('h'').fadeCut('sloB'); // utili)ar una definicin de velocidad interna
6.2.1.1 jQuery.fx.speeds
jQuery posee un objeto en j7uer".f).speeds el $ual $ontiene la velo$idad
predeterminada para la dura$i*n de un efe$toE asG $omo tambiFn los valores para las
defini$iones HsloI y HfastI.
speeds5 $
sloB5 F**;
fast5 2**;
// velocidad predeterminada
Ndefault5 E**
%
%or lo tantoE es posible sobres$ribir o a"adir nuevos valores al objeto. %or ejemploE puede
Lue Luiera $ambiar el valor predeterminado del efe$to o a"adir una velo$idad
personalizada.
.6adir velocidades personali*adas a jQuery.fx.speeds
jOuery.f<.speeds.muyDapido = '**;
jOuery.f<.speeds.muy=ento = 2***;
..2.2 5ealizar una A$$i*n +uando un -fe$to fue -je$utado
A menudoE Luerr& eje$utar una a$$i*n una vez Lue la anima$i*n :aya terminado U ya Lue
si eje$uta la a$$i*n antes Lue la anima$i*n :aya a$abadoE puede lle'ar a alterar la $alidad
del efe$to o afe$tar a los elementos Lue forman parte de la misma. W)efini$i*nN 0as
fun$iones de devolu$i*n de llamada Aen in'lFs $allba$= fun$tionsB proveen una forma para
eje$utar $*di'o una vez Lue un evento :aya terminado.X -n este $asoE el evento Lue
responder& a la fun$i*n ser& la $on$lusi*n de la anima$i*n. )entro de la fun$i*n de
devolu$i*nE la palabra $lavethis :a$e referen$ia al elemento en donde el efe$to fue
eje$utado y al i'ual Lue su$ede $on los eventosE es posible transformarlo a un objeto jQuery
utilizando $(this).
Ejecutar cierto cdigo cuando una animacin ha&a concluido
L('di6.old').fadeCut(!**; function() $ L(this).remo6e(); %);
2ote Lue si la sele$$i*n no retorna nin'8n elementoE la fun$i*n nun$a se eje$utar&. -ste
problema lo puede resolver $omprobando si la sele$$i*n devuelve al'8n elementoO y en
$aso Lue no lo :a'aE eje$utar la fun$i*n de devolu$i*n inmediatamente.
Ejecutar una !uncin de devolucin incluso si no ha& elementos para animar
var Lthing = L('Mnone<istent');

var c& = function() $
console.log('reali+ado');
%;

if (Lthing.length) $
Lthing.fade1n(!**; c&);
% else $
c&();
%
..! -fe$tos %ersonalizados $on $.fn.animate
-s posible realizar anima$iones en propiedades +SS utilizando el mFtodo $.fn.animate.
)i$:o mFtodo permite realizar una anima$i*n estable$iendo valores a propiedades +SS o
$ambiando sus valores a$tuales.
E!ectos personali*ados con $.fn.animate
L('di6.funtimes').animate(
$
left 5 Q"=#*Q;
opacity 5 *.2#
%;
!**; // duration
function() $ console.log('reali+ado'); // funcin de devolucin de llamada
%);
Nota
0as propiedades rela$ionadas al $olor no pueden ser animadas utilizando el
mFtodo $.fn.animateE pero es posible :a$erlo a travFs de la e7tensi*n $olor
plu'in. M&s adelante en el libro de dis$utir& la utiliza$i*n de e7tensiones.
1.3.1 Easin0
W)efini$i*nN -l $on$epto de -asin' des$ribe la manera en Lue un efe$to o$urre U es de$irE
si la velo$idad durante la anima$i*n es $onstante o no.X jQuery in$luye solamente dos
mFtodos de easin'N sin' y linear. Si desea transi$iones m&s naturales en las anima$ionesE
e7isten varias e7tensiones Lue lo permiten.
A partir de la versi*n 1.( de la bibliote$aE es posible estable$er el tipo de transi$i*n por
$ada propiedad utilizando el mFtodo $.fn.animate.
7ransicin de easing por cada propiedad
L('di6.funtimes').animate(
$
left 5 2 Q"=#*Q; QsBingQ 3;
opacity 5 2 *.2#; QlinearQ 3
%;
!**
);
%ara m&s detalles sobre las op$iones de easin'E $onsulte :ttpN//api.jLuery.$om/animate/.
..( +ontrol de los -fe$tos
jQuery provee varias :erramientas para el manejo de anima$iones.
@.fn.stop
)etiene las anima$iones Lue se est&n eje$utando en el elemento sele$$ionado.
@.fn.delay
-spera un tiempo determinado antes de eje$utar la pr*7ima anima$i*n.
L('h'').shoB(!**).delay('***).hide(!**);
jQuery.f7.off
Si el valor es verdadero AtrueBE no e7istir&n transi$iones para las anima$ionesO y a los
elementos se le estable$er& el estado final de la anima$i*n. -ste mFtodo puede ser
espe$ialmente 8til $uando se esta trabajando $on nave'adores anti'uos.
.., -jer$i$ios
1.#.1 Mostrar 4e5to Oculto
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/blog.js. 0a tarea es a"adir al'una
intera$tividad a la se$$i*n blo' de la p&'inaN
al :a$er $li$= en al'uno de los titulares del div Vblo'E se debe mostrar el p&rrafo
$orrespondiente $on un efe$to de deslizamientoO
al :a$er $li$= en otro titularE se debe o$ultar el p&rrafo mostrado $on un efe$to de
deslizamiento y mostrar nuevamente el p&rrafo $orrespondiente tambiFn $on un efe$to de
deslizamiento. AyudaN 2o se olvide de utilizar el sele$tor +visible.
..,.2 +rear un Men8 )esple'able
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/navigation.js. 0a tarea es poder desple'ar los
Gtems del men8 superior de la p&'inaN
al pasar el puntero del rat*n por en$ima de un Gtem del men8E se debe mostrar su submen8
en $aso Lue e7istaO
al no estar m&s en$ima de un GtemE el submen8 se debe o$ultar.
%ara poder realizarloE utili$e el mFtodo $.fn.hover para a"adir o remover una $lase en el
submen8 para poder $ontrolar si debe estar o$ulto o visible A-l ar$:ivo
/ejercicios/css/st"les.css in$luye una $lase H:overI para este prop*sitoB
..,.! +rear un Slides:o
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/slideshow.js. 0a tarea es a"adir un slides:o
a la p&'ina $on #avaS$ript.
1. Mover el elemento Vslides:o a la parte superior de la p&'ina.
2. -s$ribir un $*di'o Lue permita mostrar los Gtems de forma $G$li$aE mostrando un Gtem por
unos se'undosE lue'o o$ult&ndolo $on un efe$to fade out y mostrando el si'uiente $on un
efe$to Yfade in.
!. /na vez lle'ado al 8ltimo Gtem de la listaE $omenzar de nuevo $on el primero.
%ara un desafGo mayorE reali$e un &rea de nave'a$i*n por debajo del slides:o Lue
muestre $uantas im&'enes e7isten y en $ual se en$uentra AayudaN @.fn.prevAll] puede
resultar 8tilB.
Capitulo G
1 < Aja7
+.1 Introduccin
-l mFtodo RM0Mttp5eLuest ARM5B permite a los nave'adores $omuni$arse $on el
servidor sin la ne$esidad de re$ar'ar la p&'ina. -ste mFtodoE tambiFn $ono$ido $omo Aja7
AAsyn$:ronous #avaS$ript and RM0BE permite la $rea$i*n de apli$a$iones ri$as en
intera$tividad.
0as peti$iones Aja7 son eje$utadas por el $*di'o #avaS$riptE el $ual envGa una peti$i*n a
una /50 y $uando re$ibe una respuestaE una fun$i*n de devolu$i*n puede ser eje$utada la
$ual re$ibe $omo ar'umento la respuesta del servidor y realiza al'o $on ella. )ebido a Lue
la respuesta es asGn$ronaE el resto del $*di'o de la apli$a$i*n $ontinua eje$ut&ndoseE por lo
$ualE es imperativo Lue una fun$i*n de devolu$i*n sea eje$utada para manejar la respuesta.
A travFs de varios mFtodosE jQuery provee soporte para Aja7E permitiendo abstraer las
diferen$ias Lue pueden e7istir entre nave'adores. 0os mFtodos en $uesti*n son $.get()E
$.get$cript()E $.get8$9:()E$.post() y $().load().
A pesar Lue la defini$i*n de Aja7 posee la palabra HRM0IE la mayorGa de las apli$a$iones no
utilizan di$:o formato para el transporte de datosE sino Lue en su lu'ar se utiliza M3M0
plano o informa$i*n en formato #SO2 A#avaS$ript Obje$t 2otationB.
-n 'eneralE Aja7 no trabaja a travFs de dominios diferentes. Sin embar'oE e7isten
e7$ep$ionesE $omo los servi$ios Lue proveen informa$i*n en formato #SO2% A#SO2 it:
%addin'BE los $uales permiten una fun$ionalidad limitada a travFs de diferentes dominios.
1.2 +on$eptos +lave
0a utiliza$i*n $orre$ta de los mFtodos Aja7 reLuiere primero la $omprensi*n de al'unos
$on$eptos $lave.
+.2.1 6E4 .s. 7O*4
0os dos mFtodos M33% m&s $omunes para enviar una peti$i*n a un servidor son C-3 y
%OS3. -s importante entender la utiliza$i*n de $ada uno.
-l mFtodo C-3 debe ser utilizado para opera$iones no<destru$tivas U es de$irE
opera$iones en donde se esta HobteniendoI datos del servidorE pero no modifi$ando. %or
ejemploE una $onsulta a un servi$io de b8sLueda podrGa ser una peti$i*n C-3. %or otro
ladoE las soli$itudes C-3 pueden ser alma$enadas en la $a$:e del nave'adorE pudiendo
$ondu$ir a un $omportamiento imprede$ible si no se lo espera. CeneralmenteE la
informa$i*n enviada al servidorE es enviada en una $adena de datos Aen in'lFs Luery
strin'B.
-l mFtodo %OS3 debe ser utilizado para opera$iones destru$tivas U es de$irE opera$iones
en donde se est& in$orporando informa$i*n al servidor. %or ejemploE $uando un usuario
'uarda un artG$ulo en un blo'E esta a$$i*n deberGa utilizar %OS3. %or otro ladoE este tipo de
mFtodo no se 'uarda en la $a$:e del nave'ador. Adem&sE una $adena de datos puede ser
parte de la /50E pero la informa$i*n tiende a ser enviada de forma separada.
1.2.2 3ipos de )atos
CeneralmenteE jQuery ne$esita al'unas instru$$iones sobre el tipo de informa$i*n Lue se
espera re$ibir $uando se realiza una peti$i*n Aja7. -n al'unos $asosE el tipo de dato es
espe$ifi$ado por el nombre del mFtodoE pero en otros $asos se lo debe detallar $omo parte
de la $onfi'ura$i*n del mFtodoN
te7t
%ara el transporte de $adenas de $ara$teres simples.
:tml
%ara el transporte de bloLues de $*di'o M3M0 Lue ser&n ubi$ados en la p&'ina.
s$ript
%ara a"adir un nuevo s$ript $on $*di'o #avaS$ript a la p&'ina.
json
%ara transportar informa$i*n en formato #SO2E el $ual puede in$luir $adenas de
$ara$teresE ve$tores y objetos.
Nota
A partir de la versi*n 1.( de la bibliote$aE si la informa$i*n #SO2 no est&
$orre$tamente formateadaE la peti$i*n podrGa fallar. 9isite :ttpN//json.or' para
obtener detalles sobre un $orre$to formateo de datos en #SO2.
-s re$omendable utilizar los me$anismos Lue posea el len'uaje del lado de servidor para la
'enera$i*n de informa$i*n en formato #SO2.
jsonp
%ara transportar informa$i*n #SO2 de un dominio a otro.
7ml
%ara transportar informa$i*n en formato RM0.
A pesar de los diferentes tipos de datos de Lue se puede utilizarE es re$omendable utilizar el
formato #SO2E ya Lue es muy fle7ibleE permitiendo por ejemploE enviar al mismo tiempo
informa$i*n plana y M3M0.
1.2.! Asin$ronismo
)ebido a LueE de forma predeterminadaE las llamadas Aja7 son asGn$ronasE la respuesta del
servidor no esta disponible de forma inmediata. %or ejemploE el si'uiente $*di'o no
deberGa fun$ionarN
var response;
L.get('foo.php'; function(r) $ response = r; %);
console.log(response); // indefinido &undefined'
-n su lu'arE es ne$esario espe$ifi$ar una fun$i*n de devolu$i*n de llamadaO di$:a fun$i*n
se eje$utar& $uando la peti$i*n se :aya realizado de forma $orre$ta ya Lue es en ese
momento $uando la respuesta del servidor esta lista.
L.get('foo.php'; function(response) $ console.log(response); %);
1.2.( %olGti$as de Mismo Ori'en y #SO2%
-n 'eneralE las peti$iones Aja7 est&n limitadas a utilizar el mismo proto$olo A:ttp o :ttpsBE
el mismo puerto y el mismo dominio de ori'en. -sta limita$i*n no se apli$a a los s$ripts
$ar'ados a travFs del mFtodo Aja7 de jQuery.
0a otra e7$ep$i*n es $uando se :a$e una peti$i*n Lue re$ibir& una respuesta en formato
#SO2%. -n este $asoE el proveedor de la respuesta debe responder la peti$i*n $on un
script Lue puede ser $ar'ado utilizando la etiLueta,script-E evitando asG la limita$i*n
de realizar peti$iones desde el mismo dominio. )i$:a respuesta $ontendr& la informa$i*n
soli$itadaE $ontenida en una fun$i*n
1.2., Aja7 y Firebu'
Firebu' Ao el inspe$tor ;ebQit Lue viene in$luido en +:rome o SafariB son :erramientas
impres$indibles para trabajar $on peti$iones Aja7E ya Lue es posible observarlas desde la
pesta"a +onsola de Firebu' Ao yendo a 5e$ursos ^ %anel RM5 desde el inspe$tor de
;eb=itB y revisar los detalles de di$:as peti$iones. Si al'o esta fallando $uando trabaja $on
Aja7E este es el primer lu'ar en donde debe diri'irse para saber $ual es el problema.
1.! MFtodos Aja7 de jQuery
+omo se indi$* anteriormenteE jQuery posee varios mFtodos para trabajar $on Aja7. Sin
embar'oE todos est&n basados en el mFtodo $.aja)E por lo tantoE su $omprensi*n es
obli'atoria. A $ontinua$i*n se abar$ar& di$:o mFtodo y lue'o se indi$ar& un breve resumen
sobre los dem&s mFtodos.
CeneralmenteE es preferible utilizar el mFtodo @.aja7 en lu'ar de los otrosE ya Lue ofre$e
m&s $ara$terGsti$as y su $onfi'ura$i*n es muy $omprensible.
+.3.1 &.aja5
-l mFtodo $.aja) es $onfi'urado a travFs de un objetoE el $ual $ontiene todas las
instru$$iones Lue ne$esita jQuery para $ompletar la peti$i*n. )i$:o mFtodo es
parti$ularmente 8til debido a Lue ofre$e la posibilidad de espe$ifi$ar a$$iones en $aso Lue
la peti$i*n :aya fallado o no. Adem&sE al estar $onfi'urado a travFs de un objetoE es posible
definir sus propiedades de forma separadaE :a$iendo Lue sea m&s f&$il la reutiliza$i*n del
$*di'o. %uede visitar :ttpN//api.jLuery.$om/jQuery.aja7/ para $onsultar la do$umenta$i*n
sobre las op$iones disponibles en el mFtodo.
2tili*ar el m"todo ?(ajax
L.aja<($
// la M;" para la peticin
url 5 'post.php';

// la informacin a enviar
// &tam$in es posi$le utili)ar una cadena de datos'
data 5 $ id 5 '2! %;

// especifica si ser una peticin SB/T o U4T
type 5 'W>9';

// el tipo de informacin ,ue se espera de respuesta
data9ype 5 'json';

// cdigo a ejecutar si la peticin es satisfactoria;
// la respuesta es pasada como argumento a la funcin
success 5 function(json) $
L('<h'/>').te<t(json.title).append9o('&ody');
L('<di6 class=QcontentQ/>')
.html(json.html).append9o('&ody');
%;

// cdigo a ejecutar si la peticin falla;
// son pasados como argumentos a la funcin
// el o$jeto j,V:; &eCtensin de VL":ttp;e,uest', un teCto con el estatus
// de la peticin + un teCto con la descripcin del error ,ue ha+a dado el servidor
error 5 function(jqXAD; status; error) $
alert(':isculpe; e<isti8 un pro&lema');
%;

// cdigo a ejecutar sin importar si la peticin fall o no
complete 5 function(jqXAD; status) $
alert('Tetici8n reali+ada');
%
%);
Nota
/na a$lara$i*n sobre el par&metro data/"peN Si el servidor devuelve
informa$i*n Lue es diferente al formato espe$ifi$adoE el $*di'o fallar&E y la raz*n
de porLue lo :a$e no siempre Luedar& $lara debido a Lue la respuesta M33% no
mostrar& nin'8n tipo de error. +uando estF trabajando $on peti$iones Aja7E
debe estar se'uro Lue el servidor esta enviando el tipo de informa$i*n Lue esta
soli$itando y verifiLue Lue la $abe$era ;ontent%t"pe es e7a$ta al tipo de dato.
%or ejemploE para informa$i*n en formato #SO2E la $abe$era ;ontent%t"pe
deberGa ser application/json.
7.3.1.1 Opciones del mtodo $.ajax
-l mFtodo @.aja7 posee mu$:as op$iones de $onfi'ura$i*nE y es justamente esta
$ara$terGsti$a la Lue :a$e Lue sea un mFtodo muy 8til. %ara una lista $ompleta de las
op$iones disponiblesE puede $onsultar:ttpN//api.jLuery.$om/jQuery.aja7/O a $ontinua$i*n
se muestran las m&s $omunesN
asyn$
-stable$e si la peti$i*n ser& asGn$rona o no. )e forma predeterminada el valor es
true. )ebe tener en $uenta Lue si la op$i*n se estable$e en falseE la peti$i*n
bloLuear& la eje$u$i*n de otros $*di'os :asta Lue di$:a peti$i*n :aya finalizado.
$a$:e
-stable$e si la peti$i*n ser& 'uardada en la $a$:e del nave'ador. )e forma
predeterminada es true para todos los data3ype e7$epto para Hs$riptI y HjsonpI.
+uando posee el valor falseE se a're'a una $adena de $ara$teres anti<$a$:e al final
de la /50 de la peti$i*n.
$omplete
-stable$e una fun$i*n de devolu$i*n de llamada Lue se eje$uta $uando la peti$i*n
esta $ompletaE aunLue :aya fallado o no. 0a fun$i*n re$ibe $omo ar'umentos el
objeto jLRM5 Aen versiones anteriores o i'uales a jQuery 1.(E re$ibe en su lu'ar el
objeto de la peti$i*n en $rudo <M=6//>?e@uestB y un te7to espe$ifi$ando el estatus
de la misma peti$i*n AsuccessE notmodifiedE errorE timeoutE abortE o
parsererrorB.
$onte7t
-stable$e el al$an$e en Lue la/las fun$iones de devolu$i*n de llamada se eje$utaran
Apor ejemploE define el si'nifi$ado de this dentro de las fun$ionesB. )e manera
predeterminada this :a$e referen$ia al objeto ori'inalmente pasado al mFtodo
$.aja).
data
-stable$e la informa$i*n Lue se enviar& al servidor. -sta puede ser tanto un objeto
$omo una $adena de datos Apor ejemplo foo0bar&ba*0bim.B
data3ype
-stable$e el tipo de informa$i*n Lue se espera re$ibir $omo respuesta del servidor. Si
no se espe$ifi$a nin'8n valorE de forma predeterminadaE jQuery revisa el tipo de
M6M- Lue posee la respuesta.
error
-stable$e una fun$i*n de devolu$i*n de llamada a eje$utar si resulta al'8n error en la
peti$i*n. )i$:a fun$i*n re$ibe $omo ar'umentos el objeto jLRM5 Aen versiones
anteriores o i'uales a jQuery 1.(E re$ibe en su lu'ar el objeto de la peti$i*n en $rudo
<M=6//>?e@uestBE un te7to espe$ifi$ando el estatus de la misma peti$i*n
AtimeoutE errorE abortE o parsererrorB y un te7to $on la des$rip$i*n del error
Lue :aya enviado el servidor Apor ejemplo :ot #ound o Anternal $erver
rrorB.
jsonp
-stable$e el nombre de la fun$i*n de devolu$i*n de llamada a enviar $uando se
realiza una peti$i*n #SO2%. )e forma predeterminada el nombre es H$allba$=
su$$ess
-stable$e una fun$i*n a eje$utar si la peti$i*n a sido satisfa$toria. )i$:a fun$i*n
re$ibe $omo ar'umentos el objeto jLRM5 Aen versiones anteriores o i'uales a jQuery
1.(E re$ibe en su lu'ar el objeto de la peti$i*n en $rudo <M=6//>?e@uestBE un te7to
espe$ifi$ando el estatus de la misma peti$i*n y la informa$i*n de la peti$i*n
A$onvertida a objeto #avaS$ript en el $aso Lue data3ype sea #SO2BE el estatus de la
misma.
timeout
-stable$e un tiempo en milise'undos para $onsiderar a una peti$i*n $omo fallada.
traditional
Si su valor es trueE se utiliza el estilo de serializa$i*n de datos utilizado antes de
jQuery 1.(. %ara m&s detalles puede visitar :ttpN//api.jLuery.$om/jQuery.param/.
type
)e forma predeterminada su valor es HC-3I. Otros tipos de peti$iones tambiFn
pueden ser utilizadas A$omo %/3 y )-0-3-BE sin embar'o pueden no estar
soportados por todos los nave'adores.
url
-stable$e la /50 en donde se realiza la peti$i*n.
0a op$i*n url es obli'atoria para el mFtodo $.aja)O
+omo se $oment* anteriormenteE para una lista $ompleta de las op$iones disponiblesE
puede $onsultar:ttpN//api.jLuery.$om/jQuery.aja7/.
Nota
A partir de la versi*n 1., de jQueryE las op$iones before$endE successE
error y complete re$iben $omo uno de sus ar'umentos el objeto j@<6?
siendo este una e7tensi*n del objeto nativo<M=6//>?e@uest. -l objeto j@<6?
posee una serie de mFtodos y propiedades Lue permiten modifi$ar u obtener
informa$i*n parti$ular de la peti$i*n a realizarE $omo por ejemplo sobrees$ribir
el tipo de M6M-Lue posee la respuesta Lue se espera por parte del servidor.
%ara informa$i*n sobre el objeto j@<6?puede $onsultar
:ttpN//api.jLuery.$om/jQuery.aja7/VjLRM5.
Nota
A partir de la versi*n 1., de jQueryE las op$iones successE error y complete
pueden re$ibir un ve$tor $on varias fun$iones de devolu$i*nE las $uales ser&n
eje$utadas en turnos.
1.!.2 MFtodos +onvenientes
-n $aso Lue no Luiera utilizar el mFtodo $.aja)E y no ne$esite los $ontroladores de
erroresE e7isten otros mFtodos m&s $onvenientes para realizar peti$iones Aja7 AaunLueE
$omo se indi$* antesE estos est&n basados el mFtodo $.aja) $on valores pre<estable$idos
de $onfi'ura$i*nB.
0os mFtodos Lue provee la bibliote$a sonN
@.'et
5ealiza una peti$i*n C-3 a una /50 provista.
@.post
5ealiza una peti$i*n %OS3 a una /50 provista.
@.'etS$ript
A"ade un s$ript a la p&'ina.
@.'et#SO2
5ealiza una peti$i*n C-3 a una /50 provista y espera Lue un dato #SO2 sea
devuelto.
0os mFtodos deben tener los si'uientes ar'umentosE en ordenN
url
0a /50 en donde se realizar& la peti$i*n. Su valor es obli'atorio.
data
0a informa$i*n Lue se enviar& al servidor. Su valor es op$ional y puede ser tanto un
objeto $omo una $adena de datos A$omo foo0bar&ba*0bimB.
Nota
-sta op$i*n no es valida para el mFtodo $.get$cript.
su$$ess $allba$=
/na fun$i*n op$ional Lue se eje$uta en $aso Lue peti$i*n :aya sido satisfa$toria.
)i$:a fun$i*n re$ibe $omo ar'umentos la informa$i*n de la peti$i*n y el objeto en
bruto de di$:a peti$i*n.
data type
-l tipo de dato Lue se espera re$ibir desde el servidor. Su valor es op$ional.
Nota
-sta op$i*n es solo apli$able para mFtodos en Lue no est& espe$ifi$ado el tipo de
dato en el nombre del mismo mFtodo.
2tili*ar m"todos convenientes para peticiones .jax
// o$tiene teCto plano o html
L.get('/users.php'; $ user1d 5 '2!E %; function(resp) $
console.log(resp);
%);

// aJade un script a la pgina + luego ejecuta la funcin especificada
L.get.cript('/static/js/my.cript.js'; function() $
functionJromRy.cript();
%);

// o$tiene informacin en formato ./B# desde el servidor
L.getY.C)('/details.php'; function(resp) $
L.each(resp; function((; 6) $
console.log(( " ' 5 ' " 6);
%);
%);
1.!.! $.fn.load
-l mFtodo $.fn.load es el 8ni$o Lue se puede llamar desde una sele$$i*n. )i$:o mFtodo
obtiene el $*di'o M3M0 de una /50 y rellena a los elementos sele$$ionados $on la
informa$i*n obtenida. -n $onjunto $on la /50E es posible espe$ifi$ar op$ionalmente un
sele$torE el $ual obtendr& el $*di'o espe$ifi$ado en di$:a sele$$i*n.
2tili*ar el m"todo $.fn.load para rellenar un elemento
L('MneBKontent').load('/foo.html');
2tili*ar el m"todo $.fn.load para rellenar un elemento basado en un selector
L('MneBKontent').load('/foo.html Mmy:i6 h'5first'; function(html) $
alert('Kontenido actuali+ado');
%);
1.( Aja7 y Formularios
0as $apa$idades de jQuery $on Aja7 pueden ser espe$ialmente 8tiles para el trabajo $on
formularios. %or ejemploE la e7tensi*n jQuery Form %lu'in es una e7tensi*n para a"adir
$apa$idades Aja7 a formularios. -7isten dos mFtodos Lue debe $ono$er para $uando este
realizando este tipo de trabajosN $.fn.seriali*e y$.fn.seriali*e2rra".
7rans!ormar in!ormacin de un !ormulario a una cadena de datos
L('MmyJorm').seriali+e();
Crear un vector de objetos conteniendo in!ormacin de un !ormulario
L('MmyJorm').seriali+e?rray();

// crea una estructura como esta:
2
$ name 5 'field''; 6alue 5 '2! %;
$ name 5 'field2'; 6alue 5 'hello Borld' %
3
1., 3rabajar $on #SO2%
-n los 8ltimos tiemposE la introdu$$i*n de #SO2%E :a permitido la $rea$i*n de
apli$a$iones :Gbridas de $ontenidos. Mu$:os sitios importantes ofre$en #SO2% $omo
servi$io de informa$i*nE el $ual se a$$ede a travFs de una A%6 Aen in'lFs Appli$ation
pro'rammin' interfa$eB predefinida. /n servi$io parti$ular Lue permite obtener
informa$i*n en formato #SO2% es [a:oo_ Query 0an'ua'eE el $ual se utiliza a
$ontinua$i*n para obtenerE por ejemploE noti$ias sobre 'atosN
2tili*ar HD & JS-N:
L.aja<($
url 5 'http5//query.yahooapis.com/6'/pu&lic/yql';

// se agrega como parmetro el nom$re de la funcin de devolucin,
// seg%n se especifica en el servicio de WN"
jsonp 5 'call&ac(';

// se le indica a jNuer+ ,ue se espera informacin en formato ./B#S
data9ype 5 'jsonp';

// se le indica al servicio de WN" cual es la informacin
// ,ue se desea + ,ue se la ,uiere en formato ./B#
data 5 $
q 5 'select title;a&stract;url from search.neBs Bhere query=QcatQ';
format 5 'json'
%;

// se ejecuta una funcin al ser satisfactoria la peticin
success 5 function(response) $
console.log(response);
%
%);
jQuery se en$ar'a de solu$ionar todos los aspe$tos $omplejos de la peti$i*n #SO2%. 0o
8ni$o Lue debe :a$er es espe$ifi$ar el nombre de la fun$i*n de devolu$i*n Aen este $aso
H$allba$=IE se'8n lo espe$ifi$a [Q0B y el resultado final ser& $omo una peti$i*n Aja7
normal.
1.. -ventos Aja7
A menudoE Luerr& eje$utar una fun$i*n $uando una peti$i*n :aya $omenzado o terminadoE
$omo por ejemploE mostrar o o$ultar un indi$ador. -n lu'ar de definir estas fun$iones
dentro de $ada peti$i*nE jQuery provee la posibilidad de vin$ular eventos Aja7 a elementos
sele$$ionados. %ara una lista $ompleta de eventos Aja7E puede $onsultar
:ttpN//do$s.jLuery.$om/Aja7`-vents.
%ostrarI-cultar un indicador utili*ando Eventos .jax
L('MloadingNindicator')
.aja<.tart(function() $ L(this).shoB(); %)
.aja<.top(function() $ L(this).hide(); %);
1.1 -jer$i$ios
+.+.1 )ar0ar )ontenido E5terno
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/load.js. 0a tarea es $ar'ar el $ontenido de un
artG$ulo de blo' $uando el usuario :a'a $li$= en el tGtulo del Gtem.
1. +rear un elementos div despuFs del titulo de $ada titulo de artG$ulo de blo' y 'uardar una
referen$ia :a$ia ellos en el elemento de titulo utilizando $.fn.data.
2. 9in$ular un evento $li$= al tituloE el $ual utilizar& el mFtodo $.fn.load para $ar'ar en
$ada div $reado el $ontenido apropiado desde el ar$:ivo
/ejercicios/data/blog.html. 2o olvide de des:abilitar el $omportamiento
predeterminado del evento $li$=.
2otar Lue $ada titulo de artG$ulo de blo' en inde).html in$luye un enla$e :a$ia el
artG$ulo. 2e$esitar& aprove$:ar el atributo :ref de $ada enla$e para obtener el $ontenido
propio de blo'.:tml. /na vez obtenida el valor del atributoE puede utilizar la si'uiente
forma para pro$esar la informa$i*n y $onvertirla en un sele$tor para utilizar en $onjunto
$on $.fn.loadN
var href = '&log.htmlMpost'';
var temp?rray = href.split('M');
var id = 'M' " temp?rray2'3;
5e$uerde utilizar console.log para ase'urarse Lue esta realizando lo $orre$to.
1.1.2 +ar'ar +ontenido /tilizando #SO2
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/specials.js. 0a tarea es mostrar los detalles
del usuario para un dGa determinado $uando se sele$$iona desde la lista desple'able.
1. A"adir un elemento div despuFs del formulario Lue se en$uentra dentro del elemento
Vspe$ialsO allG ser& el lu'ar en donde se $olo$ar& la informa$i*n a obtener.
2. 9in$ular el evento $:an'e en el elemento sele$tO $uando se realiza un $ambio en la
sele$$i*nE enviar una peti$i*n Aja7 a /ejercicios/data/specials.json.
3. +uando la peti$i*n devuelve una respuestaE utilizar el valor sele$$ionado en el sele$t
AayudaN $.fn.valB para bus$ar la informa$i*n $orrespondiente en la respuesta #SO2.
4. A"adir al'8n M3M0 $on la informa$i*n obtenida en el div $reado anteriormente.
#. Finalmente remover el bot*n submit del formulario.
2otar Lue $ada vez Lue la sele$$i*n $ambiaE se realiza una peti$i*n Aja7. J+*mo $ambiarGa
el $*di'o para realizar solo una peti$i*n y 'uardar la informa$i*n para aprove$:arla
$uando se vuelve a $ambiar la op$i*n sele$$ionadaK
Capitulo J
4 < -7tensiones
-.1 89u: es una E5tensin;
/na e7tensi*n de jQuery es simplemente un nuevo mFtodo Lue se utilizar& para e7tender
el prototipo AprototypeB del objeto jQuery. +uando se e7tiende el prototipoE todos los
objetos jQuery :ereden los mFtodos a"adidos. %or lo tantoE $uando se realiza una llamada
j7uer"()E es $reado un nuevo objeto jQuery $on todos los mFtodos :eredados.
-l objetivo de una e7tensi*n es realizar una a$$i*n utilizando una $ole$$i*n de elementosE
de la misma forma Lue lo :a$enE por ejemploE los mFtodos fade9ut o add;lass de la
bibliote$a.
/sted puede realizar sus propias e7tensiones y utilizarlas de forma privada en su proye$to
o tambiFn puede publi$arlas para Lue otras personas le saLuen prove$:o.
4.2 +rear una -7tensi*n B&si$a
-l $*di'o para realizar una e7tensi*n b&si$a es la si'uienteN
(function(L)$
L.fn.my)eBTlugin = function() $
return this.each(function()$
// reali)ar algo
%);
%;
%)(jOuery);
0a e7tensi*n del prototipo del objeto jQuery o$urre en la si'uiente lGneaN
L.fn.my)eBTlugin = function() $ //222
0a $ual es en$errada en una fun$i*n autoeje$utableN
(function(L)$
//222
%)(jOuery);
-sta posee la ventaja de $rear un al$an$e HprivadoIE permitiendo utilizar el si'no dolar sin
tener la preo$upa$i*n de Lue otra bibliote$a tambiFn este utilizando di$:o si'no.
%or a:oraE internamente la e7tensi*n LuedaN
L.fn.my)eBTlugin = function() $
return this.each(function()$
// reali)ar algo
%);
%;
)entro de ellaE la palabra $lave this :a$e referen$ia al objeto jQuery en donde la
e7tensi*n es llamada.
var somejOueryC&ject = L('Msomething');

L.fn.my)eBTlugin = function() $
alert(this === somejOueryC&ject);
%;

somejOueryC&ject.my)eBTlugin(); // muestra un alerta con 'true'
-l objeto jQueryE normalmenteE $ontendr& referen$ias a varios elementos )OME es por ello
Lue a menudo se los refiere $omo una $ole$$i*n.
%ara intera$tuar $on la $ole$$i*n de elementosE es ne$esario realizar un bu$leE el $ual se
lo'ra f&$ilmente $on el mFtodo each()N
L.fn.my)eBTlugin = function() $
return this.each(function()$

%);
%;
Al i'ual Lue otros mFtodosE each() devuelve un objeto jQueryE permitiendo utilizar el
en$adenado de mFtodos A$(...).css().attr()...B. %ara no romper esta $onven$i*nE
la e7tensi*n a $rear deber& devolver el objetothisE para permitir se'uir $on el
en$adenamiento. A $ontinua$i*n se muestra un peLue"o ejemploN
(function(L)$
L.fn.shoB=in(=ocation = function() $
return this.filter('a').each(function()$
L(this).append(
' (' " L(this).attr('href') " ')'
);
%);
%;
%)(jOuery);

// 4jemplo de utili)acin:
L('a').shoB=in(=ocation();
0a e7tensi*n modifi$ar& todos los enla$es dentro de la $ole$$i*n de elementos y les a"adir&
el valor de su atributohref entre parFntesis.
<0@@ ?ntes que la e<tensi8n sea llamada5 @@>
<a href=Qpage.htmlQ>Joo</a>

<0@@ :espuVs que la e<tensi8n es llamada5 @@>
<a href=Qpage.htmlQ>Joo (page.html)</a>
3ambiFn es posible optimizar la e7tensi*nN
(function(L)$
L.fn.shoB=in(=ocation = function() $
return this.filter('a').append(function()$
return ' (' " this.href " ')';
%);
%;
%)(jOuery);
-l mFtodo append permite espe$ifi$ar una fun$i*n de devolu$i*n de llamadaE y el valor
devuelto determinar& Lue es lo Lue se a"adir& a $ada elemento. 2ote tambiFn Lue no se
utiliza el mFtodo attrE debido a Lue la A%6 nativa del )OM permite un f&$il a$$eso a la
propiedad href.
A $ontinua$i*n se muestra otro ejemplo de e7tensi*n. -n este $asoE no se reLuiere realizar
un bu$le en $ada elemento ya Lue se dele'a la fun$ionalidad dire$tamente en otro mFtodo
jQueryN
(function(L)$
L.fn.fade1n?nd?ddKlass = function(duration; class)ame) $
return this.fade1n(duration; function()$
L(this).addKlass(class)ame);
%);
%;
%)(jOuery);

// 4jemplo de utili)acin:
L('a').fade1n?nd?ddKlass(E**; 'finishedJading');
4.! -n$ontrar y -valuar -7tensiones
/no de los aspe$tos m&s populares de jQuery es la diversidad de e7tensiones Lue e7isten.
Sin embar'oE la $alidad entre e7tensiones puede variar enormemente. Mu$:as son
intensivamente probadas y bien mantenidasE pero otras son $readas de forma apresurada y
lue'o i'noradasE sin se'uir buenas pr&$ti$as.
Coo'le es la mejor :erramienta para en$ontrar e7tensiones AaunLue el eLuipo de jQuery
este trabajando para mejorar su repositorio de e7tensionesB. /na vez en$ontrada la
e7tensi*nE posiblemente Luiera $onsultar la lista de $orreos de jQuery o el $anal 65+
VjLuery para obtener la opini*n de otras personas sobre di$:a e7tensi*n.
Ase'8rese Lue la e7tensi*n este bien do$umentadaE y Lue se ofre$en ejemplos de su
utiliza$i*n. 3ambiFn ten'a $uidado $on las e7tensiones Lue realizan m&s de lo Lue
ne$esitaE estas pueden lle'ar a sobre$ar'ar su p&'ina. %ara m&s $onsejos sobre $omo
dete$tar una e7tensi*n medio$reE puede leer el artG$ulo Aen in'lFsB Si'ns of a poorly ritten
jQuery plu'in por 5emy S:arp.
/na vez sele$$ionada la e7tensi*nE ne$esitar& a"adirla a su p&'ina. %rimeroE des$ar'ue la
e7tensi*nE des$omprimala Asi es ne$esarioB y muFvala a la $arpeta de su apli$a$i*n.
Finalmente insertela utilizando el elemento s$ript Alue'o de la in$lusi*n de jQueryB.
4.( -s$ribir -7tensiones
A ve$esE desee realizar una fun$ionalidad disponible en todo el $*di'oE por ejemploE un
mFtodo Lue pueda ser llamado desde una sele$$i*n el $ual reali$e una serie de opera$iones.
0a mayorGa de las e7tensiones son mFtodos $reados dentro del espa$io de nombres $.fn.
jQuery 'arantiza Lue un mFtodo llamado sobre el objeto jQuery sea $apaz de a$$eder a
di$:o objeto a travFs de this. -n $ontrapartidaE la e7tensi*n debe 'arantizar de devolver
el mismo objeto re$ibido Aa menos Lue se e7pli$ite lo $ontrarioB.
A $ontinua$i*n se muestra un ejemploN
Crear una extensin para a6adir & remover una clase en un elemento al
suceder el evento hover
// definicin de la eCtensin
(function(L)$
L.fn.ho6erKlass = function(c) $
return this.ho6er(
function() $ L(this).toggleKlass(c); %
);
%;
%)(jOuery);

// utili)ar la eCtensin
L('li').ho6erKlass('ho6er');
%ara m&s informa$i*n sobre el desarrollo de e7tensionesE puede $onsultar el artG$ulo Aen
in'lFsB A %lu'in )evelopment %attern de Mi=e Alsup. -n di$:o artG$uloE se desarrolla una
e7tensi*n llamada $.fn.hilightE la $ual provee soporte para la e7tensi*n metadata Aen
$aso de estar presenteB y provee un mFtodo des$entralizado para estable$er op$iones
'lobales o de instan$ias de la e7tensi*n.
El patrn de desarrollo de extensiones para jDuer& explicado por %i5e .lsup
//
// crear una clausura
//
(function(L) $
//
// definicin de la eCtensin
//
L.fn.hilight = function(options) $
de&ug(this);
// generacin de las opciones principales antes de interactuar
var opts = L.e<tend($%; L.fn.hilight.defaults; options);
// se iteractua + formatea cada elemento
return this.each(function() $
Lthis = L(this);
// generacin de las opciones especificas de cada elemento
var o = L.meta 4 L.e<tend($%; opts; Lthis.data()) 5 opts;
// actuali)acin de los estilos de cada elemento
Lthis.css($
&ac(groundKolor5 o.&ac(ground;
color5 o.foreground
%);
var mar(up = Lthis.html();
// se llama a la funcin de formateo
mar(up = L.fn.hilight.format(mar(up);
Lthis.html(mar(up);
%);
%;
//
// funcin privada para reali)ar depuracin
//
function de&ug(Lo&j) $
if (BindoB.console -- BindoB.console.log)
BindoB.console.log('hilight selection count5 ' " Lo&j.si+e());
%;
//
// definir + eCponer la funcin de formateo
//
L.fn.hilight.format = function(t<t) $
return '<strong>' " t<t " '</strong>';
%;
//
// opciones predeterminadas
//
L.fn.hilight.defaults = $
foreground5 'red';
&ac(ground5 'yelloB'
%;
//
// fin de la clausura
//
%)(jOuery);
4., -s$ribir -7tensiones $on Mantenimiento de -stado /tilizando ;id'et Fa$tory de
jQuery /6
Nota
-sta se$$i*n esta basadaE $on permiso del autorE en el artG$ulo Buildin' Stateful
jQuery %lu'ins de S$ott Conzalez.
Mientras Lue la mayorGa de las e7tensiones para jQuery son sin mantenimiento de estado
Aen in'lFs statelessB U es de$irE e7tensiones Lue se eje$utan solamente sobre un elementoE
siendo esa su 8ni$a intera$$i*n U e7iste un 'ran $onjunto de fun$ionalidades Lue no se
aprove$:an en el patr*n b&si$o $on Lue se desarrollan las e7tensiones.
+on el fin de llenar ese va$GoE jQuery /6 AjQuery /ser 6nterfa$eB :a implementado un
sistema m&s avanzado de e7tensiones. -ste sistema permite manejar estados y admite
m8ltiples fun$iones para ser e7puestas en una 8ni$a e7tensi*n. )i$:o sistema es llamado
id'et fa$tory y forma parte de la versi*n 1.4 de jQuery /6 a travFs dej7uer".widgetE
aunLue tambiFn puede ser utilizado sin depender de jQuery /6.
%ara demostrar las $apa$idades de id'et fa$toryE se $rear& una e7tensi*n Lue tendr&
$omo fun$ionalidad ser una barra de pro'reso.
%or a:oraE la e7tensi*n solo permitir& estable$er el valor de la barra de pro'reso una sola
vez. -sto se realizar& llamando a j7uer".widget $on dos par&metrosN el nombre de la
e7tensi*n a $rear y un objeto literal Lue $ontendr& las fun$iones soportadas por la
e7tensi*n. +uando la e7tensi*n es llamadaE una instan$ia de ella es $reada y todas las
fun$iones se eje$utaran en el $onte7to de esa instan$ia.
-7isten dos importantes diferen$ias en $ompara$i*n $on una e7tensi*n est&ndar de
jQueryN -n primer lu'arE el $onte7to es un objetoE no un elemento )OM. -n se'undo lu'arE
el $onte7to siempre es un 8ni$o objetoE nun$a una $ole$$i*n.
2na simple extensin con mantenimiento de estado utili*ando 3idget !actor&
de jDuer& 2'
L.Bidget(Qnm(.progress&arQ; $
Ncreate5 function() $
var progress = this.options.6alue " QZQ;
this.element
.addKlass(Qprogress&arQ)
.te<t(progress);
%
%);
-l nombre de la e7tensi*n debe $ontener un espa$io de nombresE en este $aso se utiliza
nm(. 0os espa$ios de nombres tienen una limita$i*n de un solo nivel de profundidad U es
de$ir Lue por ejemploE no es posible utilizarnm(.foo. +omo se puede ver en el ejemploE
id'et fa$tory provee dos propiedades para ser utilizadas. 0a primeraE this.element es
un objeto jQuery Lue $ontiene e7a$tamente un elemento. -n $aso Lue la e7tensi*n sea
eje$utada en m&s de un elementoE una instan$ia separada de la e7tensi*n ser& $reada por
$ada elemento y $ada una tendr& su propio this.element. 0a se'unda propiedadE
this.optionsE es un $onjunto de pares $lave/valor $on todas las op$iones de la
e7tensi*n. -stas op$iones pueden pasarse a la e7tensi*n $omo se muestra a $ontinua$i*nN
Nota
+uando estF realizando sus propias e7tensiones es re$omendable utilizar su
propio espa$io de nombresE ya Lue deja en $laro de donde proviene la e7tensi*n
y si es parte de una $ole$$i*n mayor. %or otro ladoE el espa$io de nombres ui
est& reservado para las e7tensiones ofi$iales de jQuery /6.
:asar opciones al 3idget
L(Q<di6></di6>Q)
.append9o( Q&odyQ )
.progress&ar($ 6alue5 2* %);
+uando se llama a j7uer".widget se e7tiende a jQuery a"adiendo el mFtodo a
j7uer".fn Ade la misma forma Lue $uando se $rea una e7tensi*n est&ndarB. -l nombre
de la fun$i*n Lue se a"ade esta basado en el nombre Lue se pasa a j7uer".widgetE sin el
espa$io de nombres Aen este $aso el nombre ser&j7uer".fn.progressbarB.
+omo se muestra a $ontinua$i*nE es posible espe$ifi$ar valores predeterminados para
$ualLuier op$i*n. -stos valores deberGan basarse en la utiliza$i*n m&s $om8n de la
e7tensi*n.
Establecer opciones predeterminadas para un 3idget
L.Bidget(Qnm(.progress&arQ; $
// opciones predeterminadas
options5 $
6alue5 *
%;

Ncreate5 function() $
var progress = this.options.6alue " QZQ;
this.element
.addKlass( Qprogress&arQ )
.te<t( progress );
%
%);
-.#.1 A<adir M:todos a un =id0et
A:ora Lue es posible ini$ializar la e7tensi*nE es ne$esario a"adir la :abilidad de realizar
a$$iones a travFs de mFtodos definidos en la e7tensi*n. %ara definir un mFtodo en la
e7tensi*n es ne$esario in$luir la fun$i*n en el objeto literal Lue se pasa a j7uer".widget.
3ambiFn es posible definir mFtodos HprivadosI anteponiendo un 'ui*n bajo al nombre de
la fun$i*n.
Crear m"todos en el Kidget
L.Bidget(Qnm(.progress&arQ; $
options5 $
6alue5 *
%;

Ncreate5 function() $
var progress = this.options.6alue " QZQ;
this.element
.addKlass(Qprogress&arQ)
.te<t(progress);
%;

// crear un mtodo p%$lico
6alue5 function(6alue) $
// no se pasa ning%n valor, entonces act%a como mtodo o$tenedor
if (6alue === undefined) $
return this.options.6alue;
// se pasa un valor, entonces act%a como mtodo esta$lecedor
% else $
this.options.6alue = this.Nconstrain(6alue);
var progress = this.options.6alue " QZQ;
this.element.te<t(progress);
%
%;

// crear un mtodo privado
Nconstrain5 function(6alue) $
if (6alue > '**) $
6alue = '**;
%
if (6alue < *) $
6alue = *;
%
return 6alue;
%
%);
%ara llamar a un mFtodo en una instan$ia de la e7tensi*nE se debe pasar el nombre de
di$:o mFtodo a la e7tensi*n. -n $aso Lue se llame a un mFtodo Lue a$epta par&metrosE
estos se deben pasar a $ontinua$i*n del nombre del mFtodo.
lamar a m"todos en una instancia de extensin
var &ar = L(Q<di6></di6>Q)
.append9o(Q&odyQ)
.progress&ar($ 6alue5 2* %);

// o$tiene el valor actual
alert(&ar.progress&ar(Q6alueQ));

// actuali)a el valor
&ar.progress&ar(Q6alueQ; #*);

// o$tiene el valor nuevamente
alert(&ar.progress&ar(Q6alueQ));
Nota
-je$utar mFtodos pasando el nombre del mFtodo a la misma fun$i*n jQuery Lue
se utiliza para ini$ializar la e7tensi*n puede pare$er e7tra"oE sin embar'o es
realizado asG para prevenir la H$ontamina$i*nI del espa$io de nombres de
jQuery manteniendo al mismo tiempo la $apa$idad de llamar a mFtodos en
$adena.
4.,.2 3rabajar $on las Op$iones del ;id'et
/no de los mFtodos disponibles autom&ti$amente para la e7tensi*n es option. -ste
mFtodo permite obtener y estable$er op$iones despuFs de la ini$ializa$i*n y fun$iona
e7a$tamente i'ual Lue los mFtodos attr y $ss de jQueryN pasando 8ni$amente un nombre
$omo ar'umento el mFtodo fun$iona $omo obtenedorE mientras Lue pasando uno o m&s
$onjuntos de nombres y valores el mFtodo fun$iona $omo estable$edor. +uando es
utilizado $omo mFtodo obtenedorE la e7tensi*n devolver& el valor a$tual de la op$i*n
$orrespondiente al nombre pasado $omo ar'umento. %or otro ladoE $uando es utilizado
$omo un mFtodo estable$edorE el mFtodo Bset9ption de la e7tensi*n ser& llamado por
$ada op$i*n Lue se desea estable$er.
/esponder cuando una opcin es establecida
L.Bidget(Qnm(.progress&arQ; $
options5 $
6alue5 *
%;

Ncreate5 function() $
this.element.addKlass(Qprogress&arQ);
this.Nupdate();
%;

NsetCption5 function((ey; 6alue) $
this.options2(ey3 = 6alue;
this.Nupdate();
%;

Nupdate5 function() $
var progress = this.options.6alue " QZQ;
this.element.te<t(progress);
%
%);
4.,.! A"adir Fun$iones de )evolu$i*n de 0lamada
/no de las maneras m&s f&$iles de e7tender una e7tensi*n es a"adir fun$iones de
devolu$i*n de llamadaE para Lue de esta forma el usuario puede rea$$ionar $uando el
estado de la e7tensi*n $ambie. A $ontinua$i*n se mostrar& $omo a"adir una fun$i*n de
devolu$i*n de llamada a la e7tensi*n $reada para indi$ar $uando la barra de pro'reso :aya
al$anzado el 1??\. -l mFtodo Btrigger obtiene tres par&metrosN el nombre de la fun$i*n
de devolu$i*nE el objeto de evento nativo Lue ini$ializa la fun$i*n de devolu$i*n y un
$onjunto de informa$i*n relevante al evento. -l nombre de la fun$i*n de devolu$i*n es el
8ni$o par&metro obli'atorioE pero los otros pueden ser muy 8tiles si el usuario desea
implementar fun$ionalidades personalizadas.
:roveer !unciones de devolucin de llamada
L.Bidget(Qnm(.progress&arQ; $
options5 $
6alue5 *
%;

Ncreate5 function() $
this.element.addKlass(Qprogress&arQ);
this.Nupdate();
%;

NsetCption5 function((ey; 6alue) $
this.options2(ey3 = 6alue;
this.Nupdate();
%;

Nupdate5 function() $
var progress = this.options.6alue " QZQ;
this.element.te<t(progress);
if (this.options.6alue == '**) $
this.Ntrigger(QcompleteQ; null; $ 6alue5 '** %);
%
%
%);
0as fun$iones de devolu$i*n son esen$ialmente s*lo op$iones adi$ionalesE por lo $ualE
pueden ser estable$idas $omo $ualLuier otra op$i*n. +ada vez Lue una fun$i*n de
devolu$i*n es eje$utadaE un evento $orrespondiente se a$tiva tambiFn. -l tipo de evento se
determina mediante la $on$atena$i*n del nombre de la e7tensi*n y el nombre de la fun$i*n
de devolu$i*n. )i$:a fun$i*n y evento re$iben dos mismos par&metrosN un objeto de
evento y un $onjunto de informa$i*n relevante al evento.
Si la e7tensi*n tendr& al'una fun$ionalidad Lue podr& ser $an$elada por el usuarioE la
mejor manera de :a$erlo es $reando fun$iones de devolu$i*n $an$elables. -l usuario podr&
$an$elar una fun$i*n de devolu$i*n o su evento aso$iado de la misma manera Lue se
$an$ela $ualLuier evento nativoN llamando a event.preventDefault() o utilizando
return false.
0incular a eventos del 3idget
var &ar = L(Q<di6></di6>Q)
.append9o(Q&odyQ)
.progress&ar($
complete5 function(e6ent; data) $
alert( QJunci8n de de6oluci8nQ );
%
%)
.on(Qprogress&arcompleteQ; function(e6ent; data) $
alert(Q>l 6alor de la &arra de progreso es Q " data.6alue);
%);

&ar.progress&ar(QoptionQ; Q6alueQ; '**);
En pro!undidadL Kidget )actor&
+uando se llama a j7uer".widgetE Fsta $rea una fun$i*n $onstru$tora para la e7tensi*n
y estable$e el objeto literal Lue se pasa $omo el prototipo para todas las instan$ias de la
e7tensi*n. 3odas las fun$ionalidades Lue autom&ti$amente se a"aden a la e7tensi*n
provienen del prototipo base del id'etE el $ual es definido
$omoj7uer".Cidget.protot"pe. +uando una instan$ia de la e7tensi*n es $readaE es
'uardada en el elemento )OM ori'inal utilizando j7uer".dataE $on el nombre de la
e7tensi*n $omo palabra $lave.
)ebido a Lue la instan$ia de la e7tensi*n esta dire$tamente vin$ulada al elemento )OME es
posible a$$eder a la instan$ia de la e7tensi*n de forma dire$ta. -sto permite llamar a
mFtodos dire$tamente en la instan$ia de la e7tensi*n en lu'ar de pasar el nombre del
mFtodo $omo una $adena de $ara$teresE dando la posibilidad de a$$eder a las propiedades
de la e7tensi*n.
var &ar = L(Q<di6></di6>Q)
.append9o(Q&odyQ)
.progress&ar()
.data(Qprogress&arQ );

// llamar a un mtodo directamente en la instancia de la eCtensin
&ar.option(Q6alueQ; #*);

// acceder a propiedades en la instancia de la eCtensin
alert(&ar.options.6alue);
/no de los mayores benefi$ios de tener un $onstru$tor y un prototipo para una e7tensi*n
es la fa$ilidad de e7tender la e7tensi*n. -l :e$:o de a"adir o $ambiar mFtodos en el
prototipo de la e7tensi*nE permite tambiFn modifi$arlos en todas las instan$ias de la
e7tensi*n. %or ejemploE si deseamos a"adir un mFtodo a la e7tensi*n de barra de pro'reso
para permitir restable$er el pro'reso a ?\E es posible :a$erlo a"adiendo este mFtodo al
prototipo y autom&ti$amente estar& disponible para ser llamada desde $ualLuier instan$ia
de la e7tensi*n.
L.nm(.progress&ar.prototype.reset = function() $
this.NsetCption(Q6alueQ; *);
%;
4.,.( 0impieza
-n al'unos $asosE tendr& sentido permitir a los usuarios apli$ar y desapli$ar la e7tensi*n.
-sto es posible :a$erlo a travFs del mFtodo destro". +on di$:o mFtodoE es posible
des:a$er todo lo realizado $on la e7tensi*n. 3ambiFn Fste es llamado autom&ti$amente si
el elemento vin$ulado a la e7tensi*n es eliminado del )OM Apor lo $ual tambiFn es posible
utilizarlo para la Hre$ole$$i*n de basuraIB. -l mFtodo destro" predeterminado remueve el
vGn$ulo entre el elemento )OM y la instan$ia de la e7tensi*n
.6adir un m"todo destro& al 3idget
L.Bidget( Qnm(.progress&arQ; $
options5 $
6alue5 *
%;

Ncreate5 function() $
this.element.addKlass(Qprogress&arQ);
this.Nupdate();
%;

NsetCption5 function((ey; 6alue) $
this.options2(ey3 = 6alue;
this.Nupdate();
%;

Nupdate5 function() $
var progress = this.options.6alue " QZQ;
this.element.te<t(progress);
if (this.options.6alue == '** ) $
this.Ntrigger(QcompleteQ; null; $ 6alue5 '** %);
%
%;

destroy5 function() $
this.element
.remo6eKlass(Qprogress&arQ)
.te<t(QQ);

// llama a la funcin $ase destro+
L.Pidget.prototype.destroy.call(this);
%
%);
4.,., +on$lusi*n
0a utiliza$i*n de ;id'et fa$tory es solo una manera de $rear e7tensiones $on
mantenimiento de estado. -7isten al'unos modelos diferentes Lue pueden ser utilizados y
$ada uno posee sus ventajas y desventajas. ;id'et fa$tory resuelve mu$:os problemas
$omunesE mejora si'nifi$ativamente la produ$tividad y la reutiliza$i*n de $*di'o.
4.. -jer$i$ios
-.1.1 >ealizar una 4abla Ordenable
%ara este ejer$i$ioE la tarea es identifi$arE des$ar'ar e implementar una e7tensi*n Lue
permita ordenar la tabla e7istente en la p&'ina inde7.:tml. +uando estF listoE todas las
$olumnas de la tabla deben poder ser ordenables.
4...2 -s$ribir una -7tensi*n %ara +ambiar el +olor de Fondo en 3ablas
Abra el ar$:ivo /ejercicios/inde).html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/stripe.js. 0a tarea es es$ribir una e7tensi*n
llamada HstripeI la $ual podr& ser llamada desde $ualLuier elemento table y deber&
$ambiar el $olor de fondo de las filas impares en el $uerpo de la tabla. -l $olor podr& ser
espe$ifi$ado $omo par&metro de la e7tensi*n.
L('Mmy9a&le').stripe('Mcccccc');
2o olvide de devolver la tabla para Lue otros mFtodos puedan ser en$adenados lue'o de la
llamada a la e7tensi*n.
Capitulo M
> < Mejores %r&$ti$as para Aumentar el 5endimiento
-ste $apGtulo $ubre numerosas mejores pr&$ti$as de #avaS$ript y jQueryEsin un orden en
parti$ular. Mu$:as de estas pr&$ti$as est&n basadas en la presenta$i*n jQuery Anti<
%atterns for %erforman$e Aen in'lFsB de %aul 6ris:.
%.1 6uardar la ?on0itud en Bucles
-n un bu$leE no es ne$esario a$$eder a la lon'itud de un ve$tor $ada vez Lue se eval8a la
$ondi$i*nO di$:o valor se puede 'uardar previamente en una variable.
var my=ength = my?rray.length;

for (var i = *; i < my=ength; i"") $
// do stuff
%
>.2 A"adir 2uevo +ontenido por Fuera de un Bu$le
Si va a insertar mu$:os elementos en el )OME :&'alo todo de una sola vezE no de una por
vez.
// mal
L.each(my?rray; function(i; item) $
var neB=ist1tem = '<li>' " item " '</li>';
L('M&allers').append(neB=ist1tem);
%);

// mejor: reali)ar esto
var frag = document.create:ocumentJragment();

L.each(my?rray; function(i; item) $
var neB=ist1tem = '<li>' " item " '</li>';
frag.appendKhild(neB=ist1tem);
%);
L('M&allers')2*3.appendKhild(frag);

// o esto:
var myAtml = '';

L.each(my?rray; function(i; item) $
myAtml "= '<li>' " item " '</li>';
%);
L('M&allers').html(myAtml);
>.! 2o 5epetirse
2o se repitaO reali$e las $osas una vez y s*lo unaE $aso $ontrario lo estar& :a$iendo mal.
// L5"
if (Le6entfade.data('currently') 0= 'shoBing') $
Le6entfade.stop();
%

if (Le6entho6er.data('currently') 0= 'shoBing') $
Le6entho6er.stop();
%

if (Lspans.data('currently') 0= 'shoBing') $
Lspans.stop();
%

// *74#
var Lelems = 2Le6entfade; Le6entho6er; Lspans3;
L.each(Lelems; function(i;elem) $
if (elem.data('currently') 0= 'shoBing') $
elem.stop();
%
%);
>.( +uidado $on las Fun$iones An*nimas
2o es a$onsejable utilizar de sobremanera las fun$iones an*nimas. -stas son difG$iles de
depurarE mantenerE probar o reutilizar. -n su lu'arEutili$e un objeto literal para or'anizar y
nombrar sus $ontroladores y fun$iones de devolu$i*n de llamada.
// L5"
L(document).ready(function() $
L('Mmagic').clic((function(e) $
L('Myayeffects').slideSp(function() $
// 222
%);
%);

L('Mhappiness').load(url " ' Municorns'; function() $
// 222
%);
%);

// L4.B;
var T1 = $
onDeady 5 function() $
L('Mmagic').clic((T1.candyRtn);
L('Mhappiness').load(T1.url " ' Municorns'; T1.unicornK&);
%;

candyRtn 5 function(e) $
L('Myayeffects').slideSp(T1.slideK&);
%;

slideK& 5 function() $ ... %;

unicornK& 5 function() $ ... %
%;

L(document).ready(T1.onDeady);
>., Optimiza$i*n de Sele$tores
0a optimiza$i*n de sele$tores es menos importante de lo Lue solGa serE debido a la
implementa$i*n en al'unos nave'adores dedocument.@uer"$elector2ll()E pasando
la $ar'a de jQuery :a$ia el nave'ador. Sin embar'oE e7isten al'unos $onsejos Lue debe
tener en $uenta.
%.#.1 *electores basados en I/
Siempre es mejor $omenzar las sele$$iones $on un 6).
// rpido
L('Mcontainer di6.ro&otarm');

// super1rpido
L('Mcontainer').find('di6.ro&otarm');
-l ejemplo Lue utiliza $.fn.find es m&s r&pido debido a Lue la primera sele$$i*n utiliza
el motor de sele$$i*n interno Sizzle U mientras Lue la sele$$i*n realizada 8ni$amente por
6) utiliza document.getlement3"Ad()E el $ual es e7tremadamente r&pido debido a
Lue es una fun$i*n nativa del nave'ador.
>.,.2 -spe$ifi$idad
3rate de ser espe$ifi$o para el lado dere$:o de la sele$$i*n y menos espe$Gfi$o para el
izLuierdo.
// no optimi)ado
L('di6.data .gon+ale+');

// optimi)ado
L('.data td.gon+ale+');
/se en lo posible eti@ueta.clase del lado dere$:o de la sele$$i*nE y solo eti@ueta o
.clase en la parte izLuierda.
L('.data ta&le.attendees td.gon+ale+');

// mucho mejor: eliminar la parte media de ser posi$le
L('.data td.gon+ale+');
0a se'unda sele$$i*n tiene mejor rendimiento debido a Lue atraviesa menos $apas para
bus$ar el elemento.
>.,.! -vitar el Sele$tor /niversal
Sele$$iones en donde se espe$ifi$a de forma implG$ita o e7plG$ita una sele$$i*n universal
puede resultar muy lento.
L('.&uttons > '); // mu+ lento
L('.&uttons').children(); // mucho mejor

L('.gender 5radio'); // seleccin universal impl-cita
L('.gender 5radio'); // misma forma, pero de forma eCpl-cita
L('.gender input5radio'); // mucho mejor
>.. /tilizar la )ele'a$i*n de -ventos
0a dele'a$i*n de eventos permite vin$ular un $ontrolador de evento a un elemento
$ontenedor Apor ejemploE una lista desordenadaB en lu'ar de m8ltiples elementos
$ontenidos Apor ejemploE los Gtems de una listaB. jQuery :a$e f&$il este trabajo a travFs de
$.fn.live y$.fn.delegate. -n lo posibleE es re$omendable utilizar$.fn.delegate
en lu'ar de $.fn.liveE ya Lue elimina la ne$esidad de una sele$$i*n y su $onte7to
e7plG$ito redu$e la $ar'a en apro7imadamente un 4?\.
Adem&sE la dele'a$i*n de eventos permite a"adir nuevos elementos $ontenedores a la
p&'ina sin tener Lue volver a vin$ular sus $ontroladores de eventos.
// mal &si eCisten muchos items en la lista'
L('li.trigger').clic((handlerJn);

// mejor: delegacin de eventos con R2fn2live
L('li.trigger').li6e('clic('; handlerJn);

// mucho mejor: delegacin de eventos con R2fn2delegate
// permite especificar un conteCto de forma fcil
L('Mmy=ist').delegate('li.trigger'; 'clic('; handlerJn);
>.1 Separar -lementos para 3rabajar $on -llos
-n lo posibleE :ay Lue evitar la manipula$i*n del )OM. %ara ayudar $on este prop*sitoE a
partir de la versi*n 1.(E jQuery introdu$e $.fn.detach el $ual permite trabajar elementos
de forma separada del )OM para lue'o insertarlos.
var Lta&le = L('Mmy9a&le');
var Lparent = Lta&le.parent();

Lta&le.detach();
// 222 se aJaden muchas celdas a la ta$la
Lparent.append(ta&le);
>.4 /tilizar -stilos en +as$ada para +ambios de +SS en 9arios -lementos
Si va a $ambiar el +SS en m&s de 2? elementos utilizando $.fn.cssE $onsidere realizar los
$ambios de estilos a"adiFndolos en una etiLueta style. )e esta forma se in$rementa un
.?\ el rendimiento.
// correcto hasta 2( elementos, lento en ms elementos
L('a.sBed&erg').css('color'; 'Masd'2!');
L('<style type=Qte<t/cssQ>a.sBed&erg $ color 5 Masd'2! %</style>')
.append9o('head');
>.> /tilizar $.data en 0u'ar de $.fn.data
/tilizar $.data en un elemento del )OM en lu'ar de $.fn.data en una sele$$i*n puede
ser :asta 1? ve$es m&s r&pido. Antes de realizarloE este se'uro de $omprender la diferen$ia
entre un elemento )OM y una sele$$i*n jQuery.
// regular
L(elem).data((ey;6alue);

// 1( veces ms rpido
L.data(elem;(ey;6alue);
>.1? 2o A$tuar en -lementos no -7istentes
jQuery no le dir& si esta tratando de eje$utar $*di'o en una sele$$i*n va$Ga U esta se
eje$utar& $omo si nada estuviera mal. )epender& de usted $omprobar si la sele$$i*n
$ontiene elementos.
// L5": el cdigo a continuacin ejecuta tres funciones
// sin compro$ar si eCisten elementos
// en la seleccin
L('Mnosuchthing').slideSp();

// Lejor
var Lmy.election = L('Mnosuchthing');
if (Lmy.election.length) $ Lmy.election.slideSp(); %

// LM=:B L4.B;: aJadir una eCtensin doBnce
jOuery.fn.doCnce = function(func)$
this.length -- func.apply(this);
return this;

%


L('li.cartitems').doCnce(function()$

// reali)ar algo

%);
-ste $onsejo es espe$ialmente apli$able para id'ets de jQuery /6E los $uales poseen
mu$:a $ar'a in$luso $uando la sele$$i*n no $ontiene elementos.
>.11 )efini$i*n de 9ariables
0as variables pueden ser definidas en una sola de$lara$i*n en lu'ar de varias.
// antiguo
var test = ';
var test2 = function() $ ... %;
var test! = test2(test);

// mejor forma
var test = ';
test2 = function() $ ... %;
test! = test2(test);
-n fun$iones autoeje$utablesE las defini$iones de variables pueden pasarse todas juntas.
(function(foo; &ar) $ ... %)('; 2);
>.12 +ondi$ionales
// antiguo
if (type == 'foo' ,, type == '&ar') $ ... %

// mejor
if (/[(foo,&ar)L/.test(type)) $ ... %

// $%s,ueda en o$jeto literal
if (($ foo 5 '; &ar 5 ' %)2type3) $ ... %
>.1! 2o 3ratar a jQuery $omo si fuera una +aja 2e'ra
/tili$e el $*di'o fuente de la bibliote$a $omo si fuera su do$umenta$i*n U 'uarde el enla$e
:ttpN//bit.ly/jLsour$e$omo mar$ador para tener de referen$ia.
Capitulo NO
1? < Or'aniza$i*n del +*di'o
1@.1 Introduccin
+uando se emprende la tarea de realizar apli$a$iones $omplejas del lado del $lienteE es
ne$esario $onsiderar la forma en Lue se or'anizar& el $*di'o. -ste $apitulo est& dedi$ado a
analizar al'unos patrones de or'aniza$i*n de $*di'o para utilizar en una apli$a$i*n
realizada $on jQuery. Adem&s se e7plorar& el sistema de 'esti*n de dependen$ias de
5eLuire#S.
1@.1.1 )onceptos )la.e
Antes de $omenzar $on los patrones de or'aniza$i*n de $*di'oE es importante entender
al'unos $on$eptos $laveN
el $*di'o debe estar divido en unidades fun$ionales U m*dulosE servi$iosE et$. [ se debe
evitar la tenta$i*n de tener todo en un 8ni$o bloLue $(document).read"(). -ste
$on$epto se $ono$e $omo en$apsula$i*nO
no repetir $*di'o. 6dentifi$ar piezas similares y utilizar tF$ni$as de :ereda$i*nO
a pesar de la naturaleza de jQueryE no todas las apli$a$iones #avaS$ript trabajan Ao tienen
la ne$esidad de poseer una representa$i*nB en el )OMO
las unidades de fun$ionalidad deben tener una arti$ula$i*n fle7ible Aen in'lFs loosely
$oupledB U es de$irE una unidad de fun$ionalidad debe ser $apaz de e7istir por si misma y
la $omuni$a$i*n $on otras unidades debe ser a travFs de un sistema de mensajes $omo los
eventos personalizados o pub/sub. %or otro ladoE siempre Lue sea posibleE de debe
mantener alejada la $omuni$a$i*n dire$ta entre unidades fun$ionales.
-l $on$epto de arti$ula$i*n fle7ible puede ser espe$ialmente problem&ti$o para
desarrolladores Lue :a$en su primera in$ursi*n en apli$a$iones $omplejas. %or lo tantoE si
usted esta empezando a $rear apli$a$ionesE solamente sea $ons$iente de este $on$epto.
1?.2 -n$apsula$i*n
-l primer paso para la or'aniza$i*n del $*di'o es separar la apli$a$i*n en distintas piezas.
Mu$:as ve$esE este esfuerzo suele ser sufi$iente para mantener al $*di'o en orden.
1@.2.1 El Objeto ?iteral
/n objeto literal es tal vez la manera m&s simple de en$apsular $*di'o rela$ionado. -ste no
ofre$e nin'una priva$idad para propiedades o mFtodosE pero es 8til para eliminar
fun$iones an*nimasE $entralizar op$iones de $onfi'ura$i*nE y fa$ilitar el $amino para la
reutiliza$i*n y refa$toriza$i*n.
2n objeto literal
var myJeature = $
myTroperty 5 'hello';

myRethod 5 function() $
console.log(myJeature.myTroperty);
%;

init 5 function(settings) $
myJeature.settings = settings;
%;

read.ettings 5 function() $
console.log(myJeature.settings);
%
%;

myJeature.myTroperty; // 'hello'
myJeature.myRethod(); // registra 'hello'
myJeature.init($ foo 5 '&ar' %);
myJeature.read.ettings(); // registra P foo : '$ar' Q
-l objeto posee una propiedad y varios mFtodosE los $uales son p8bli$os Aes de$irE
$ualLuier parte de la apli$a$i*n puede verlosB. J+*mo se puede apli$ar este patr*n $on
jQueryK %or ejemploE en el si'uiente $*di'o es$rito en el estilo tradi$ionalN
// haciendo clic en un item de la lista se carga cierto contenido,
// luego utili)ando el 7D de dicho item se ocultan
// los items aledaJos
L(document).ready(function() $
L('MmyJeature li')
.append('<di6/>')
.clic((function() $
var Lthis = L(this);
var Ldi6 = Lthis.find('di6');
Ldi6.load('foo.php4item=' "
Lthis.attr('id');
function() $
Ldi6.shoB();
Lthis.si&lings()
.find('di6').hide();
%
);
%);
%);
Si el ejemplo mostrado representa el 1??\ de la apli$a$i*nE es $onveniente dejarlo $omo
estaE ya Lue no amerita :a$er una reestru$tura$i*n. -n $ambioE si la pieza es parte de una
apli$a$i*n m&s 'randeE estarGa bien separar di$:a fun$ionalidad de otras no rela$ionadas.
%or ejemploE es $onveniente mover la /50 a la $ual se :a$e la peti$i*n fuera del $*di'o y
pasarla al &rea de $onfi'ura$i*n. 3ambiFn romper la $adena de mFtodos para :a$er lue'o
m&s f&$il la modifi$a$i*n.
2tili*ar un objeto literal para una !uncionalidad jDuer&
var myJeature = $
init 5 function(settings) $
myJeature.config = $
Litems 5 L('MmyJeature li');
Lcontainer 5 L('<di6 class=QcontainerQ></di6>');
url/ase 5 '/foo.php4item='
%;

// permite so$reescri$ir la configuracin predeterminada
L.e<tend(myJeature.config; settings);

myJeature.setup();
%;

setup 5 function() $
myJeature.config.Litems
.each(myJeature.createKontainer)
.clic((myJeature.shoB1tem);
%;

createKontainer 5 function() $
var Li = L(this);
Lc = myJeature.config.Lcontainer.clone()
.append9o(Li);

Li.data('container'; Lc);
%;

&uildSrl 5 function() $
return myJeature.config.url/ase "
myJeature.Lcurrent1tem.attr('id');
%;

shoB1tem 5 function() $
var myJeature.Lcurrent1tem = L(this);
myJeature.getKontent(myJeature.shoBKontent);
%;

getKontent 5 function(call&ac() $
var url = myJeature.&uildSrl();
myJeature.Lcurrent1tem
.data('container').load(url; call&ac();
%;

shoBKontent 5 function() $
myJeature.Lcurrent1tem
.data('container').shoB();
myJeature.hideKontent();
%;

hideKontent 5 function() $
myJeature.Lcurrent1tem.si&lings()
.each(function() $
L(this).data('container').hide();
%);
%
%;

L(document).ready(myJeature.init);
0a primera $ara$terGsti$a a notar es Lue el $*di'o es m&s lar'o Lue el ori'inal U $omo se
dijo anteriormenteE si este fuera el al$an$e de la apli$a$i*nE utilizar un objeto literal seria
probablemente una e7a'era$i*n.
+on la nueva or'aniza$i*nE las ventajas obtenidas sonN
separa$i*n de $ada fun$ionalidad en peLue"os mFtodos. -n un futuroE si se Luiere $ambiar
la forma en Lue el $ontenido se muestraE ser& $laro en donde :abr& Lue :a$erlo. -n el
$*di'o ori'inalE este paso es mu$:o m&s difG$il de lo$alizarO
se eliminaron los usos de fun$iones an*nimasO
las op$iones de $onfi'ura$i*n se movieron a una ubi$a$i*n $entralO
se eliminaron las limita$iones Lue poseen las $adenas de mFtodosE :a$iendo Lue el $*di'o
sea m&s f&$il para refa$torizarE mez$lar y reor'anizar.
%or sus $ara$terGsti$asE la utiliza$i*n de objetos literales permiten una $lara mejora para
tramos lar'os de $*di'o insertados en un bloLue $(document).read"(). Sin embar'oE
no son m&s avanzados Lue tener varias de$lara$iones de fun$iones dentro de un bloLue $
(document).read"().
1?.2.2 -l %atr*n Modular
-l patr*n modular supera al'unas limita$iones del objeto literalE ofre$iendo priva$idad
para variables y fun$ionesE e7poniendo a su vez Asi se lo deseaB una A%6 p8bli$a.
El patrn modular
var feature =(function() $

// varia$les + funciones privadas
var pri6ate9hing = 'secret';
pu&lic9hing = 'not secret';

changeTri6ate9hing = function() $
pri6ate9hing = 'super secret';
%;

sayTri6ate9hing = function() $
console.log(pri6ate9hing);
changeTri6ate9hing();
%;

// 5S7 pu$lica
return $
pu&lic9hing 5 pu&lic9hing;
sayTri6ate9hing 5 sayTri6ate9hing
%

%)();

feature.pu&lic9hing; // registra 'not secret'

feature.sayTri6ate9hing();
// registra 'secret' + cam$ia el valor
// de privateThing
-n el ejemploE se autoeje$uta una fun$i*n an*nima la $ual devuelve un objeto. )entro de la
fun$i*nE se definen al'unas variables. )ebido a Lue ellas son definidas dentro de la
fun$i*nE desde afuera no se tiene a$$eso a menos Lue se pon'an dentro del objeto Lue se
devuelve. -sto impli$a Lue nin'8n $*di'o fuera de la fun$i*n tiene a$$eso a la variable
private/hing o a la fun$i*n sa">rivate/hing. Sin embar'oE sa">rivate/hing
posee a$$eso a private/hing y change>rivate/hing debido a estar definidos en el
mismo al$an$e.
-l patr*n es poderoso debido a Lue permite tener variables y fun$iones privadasE
e7poniendo una A%6 limitada $onsistente en devolver propiedades y mFtodos de un objeto.
A $ontinua$i*n se muestra una revisi*n del ejemplo visto anteriormenteE $on las mismas
$ara$terGsti$asE pero e7poniendo un 8ni$o mFtodo p8bli$o del moduloE
showAtem3"Ande)().
2tili*ar el patrn modular para una !uncionalidad jDuer&
L(document).ready(function() $
var feature = (function() $

var Litems = L('MmyJeature li');
Lcontainer = L('<di6 class=QcontainerQ></di6>');
Lcurrent1tem;

url/ase = '/foo.php4item=';

createKontainer = function() $
var Li = L(this);
Lc = Lcontainer.clone().append9o(Li);

Li.data('container'; Lc);
%;

&uildSrl = function() $
return url/ase " Lcurrent1tem.attr('id');
%;

shoB1tem = function() $
var Lcurrent1tem = L(this);
getKontent(shoBKontent);
%;

shoB1tem/y1nde< = function(id<) $
L.pro<y(shoB1tem; Litems.get(id<));
%;

getKontent = function(call&ac() $
Lcurrent1tem.data('container').load(&uildSrl(); call&ac();
%;

shoBKontent = function() $
Lcurrent1tem.data('container').shoB();
hideKontent();
%;

hideKontent = function() $
Lcurrent1tem.si&lings()
.each(function() $
L(this).data('container').hide();
%);
%;

Litems
.each(createKontainer)
.clic((shoB1tem);

return $ shoB1tem/y1nde< 5 shoB1tem/y1nde< %;
%)();

feature.shoB1tem/y1nde<(*);
%);
1?.! Cesti*n de )ependen$ias
Nota
-sta se$$i*n esta basada en la e7$elente do$umenta$i*n de 5eLuire#S y es
utilizada $on el permiso de #ames Bur=eE autor de 5eLuire#S.
+uando un proye$to al$anza $ierto tama"oE $omienza a ser difG$il el manejo de los m*dulos
de una apli$a$i*nE ya Lue es ne$esario saber ordenarlos de forma $orre$taE y $omenzar a
$ombinarlos en un 8ni$o ar$:ivo para lo'rar la menor $antidad de peti$iones. 3ambiFn es
posible Lue se Luiera $ar'ar $*di'o Hal vueloI lue'o de la $ar'a de la p&'ina.
5eLuire#S es una :erramienta de 'esti*n de dependen$ias $reada por #ames Bur=eE la $ual
ayuda a manejar los m*dulosE $ar'arlos en un orden $orre$to y $ombinarlos de forma f&$il
sin tener Lue realizar nin'8n $ambio. A su vezE otor'a una manera f&$il de $ar'ar $*di'o
una vez $ar'ada la p&'inaE permitiendo minimizar el tiempo de des$ar'a.
5eLuire#S posee un sistema modularE Lue sin embar'oE no es ne$esario se'uirlo para
obtener sus benefi$ios. -l formato modular de 5eLuire#S permite la es$ritura de $*di'o
en$apsuladoE in$orpora$i*n de interna$ionaliza$i*n Ai14nB a los paLuetes Apara permitir
utilizarlos en diferentes len'uajesB e in$luso la utiliza$i*n de servi$ios #SO2% $omo
dependen$ias.
1@.3.1 Obtener >eAuireB*
0a manera m&s f&$il de utilizar 5eLuire#S $on jQuery es des$ar'ando el paLuete de jQuery
$on 5eLuire#S ya in$orporado en Fl. -ste paLuete e7$luye por$iones de $*di'o Lue
dupli$an fun$iones de jQuery. 3ambiFn es 8til des$ar'ar un ejemplo de proye$to jQuery
Lue utiliza 5eLuire#S.
1?.!.2 /tilizar 5eLuire#S $on jQuery
/tilizar 5eLuire#S es simpleE tan solo es ne$esario in$orporar en la p&'ina la versi*n de
jQuery Lue posee 5eLuire#S in$orporado y a $ontinua$i*n soli$itar los ar$:ivos de la
apli$a$i*n. -l si'uiente ejemplo asume Lue tanto jQuery $omo los otros ar$:ivos est&n
dentro de la $arpeta scripts/.
2tili*ar /e1uireJSL 2n ejemplo simple
<0:CK9\T> html>
<html>
<head>
<title>jOuery"DequireY. .ample Tage</title>
<script src=Qscripts/require@jquery.jsQ></script>
<script>require(2QappQ3);</script>
</head>
<&ody>
<h'>jOuery"DequireY. .ample Tage</h'>
</&ody>
</html>
0a llamada a re@uire(DEappEF) le di$e a 5eLuire#S Lue $ar'ue el ar$:ivo
scripts/app.js. 5eLuire#S $ar'ar& $ualLuier dependen$ia pasada a re@uire() sin la
e7tensi*n .js desde el mismo dire$torio Lue en Lue se en$uentra el ar$:ivo re@uire%
j@uer".jsE aunLue tambiFn es posible espe$ifi$ar la ruta de la si'uiente formaN
<script>require(2Qscripts/app.jsQ3);</script>
-l ar$:ivo app.js es otra llamada a re@uire.js para $ar'ar todos los ar$:ivos
ne$esarios para la apli$a$i*n. -n el si'uiente ejemploE app.js soli$ita dos e7tensiones
j@uer".alpha.js y j@uer".beta.js Ano son e7tensiones realesE solo ejemplosB. -stas
e7tensiones est&n en la misma $arpeta Lue re@uire%j@uer".jsN
2n simple archivo JavaScript con dependencias
require(2Qjquery.alphaQ; Qjquery.&etaQ3; function() $
//las eCtensiones j,uer+2alpha2js + j,uer+2$eta2js han sido cargadas2
L(function() $
L('&ody').alpha().&eta();
%);
%);
1?.!.! +rear M*dulos 5eusables $on 5eLuire#S
5eLuire#S :a$e Lue sea f&$il definir m*dulos reusables a travFs de re@uire.def(). /n
modulo 5eLuire#S puede tener dependen$ias Lue pueden ser utilizadas para definir un
m*duloE adem&s de poder devolver un valor U un objetoE una fun$i*nE u otra $osa U Lue
puede ser in$luso utilizado otros m*dulos.
Si el m*dulo no posee nin'una dependen$iaE tan solo se debe espe$ifi$ar el nombre $omo
primer ar'umento dere@uire.def(). -l se'undo ar'umento es un objeto literal Lue
define las propiedades del m*dulo. %or ejemploN
De!inicin de un mdulo /e1uireJS 1ue no posee dependencias
require.def(Qmy/simpleshirtQ;
$
color5 Q&lac(Q;
si+e5 Qunisi+eQ
%
);
-l ejemplo debe ser 'uardado en el ar$:ivo m"/simpleshirt.js.
Si el modulo posee dependen$iasE es posible espe$ifi$arlas en el se'undo ar'umento de
re@uire.def() a travFs de un ve$torB y lue'o pasar una fun$i*n $omo ter$er ar'umento.
-sta fun$i*n ser& llamada para definir el m*dulo una vez $ar'adas todos las dependen$ias.
)i$:a fun$i*n re$ibe los valores devueltos por las dependen$ias $omo un ar'umento Aen el
mismo orden en Lue son reLueridas en el ve$torB y lue'o la misma debe devolver un objeto
Lue defina el m*dulo.
De!inicin de un mdulo /e1uireJS con dependencias
require.def(Qmy/shirtQ;
2Qmy/cartQ; Qmy/in6entoryQ3;
function(cart; in6entory) $
//devuelve un o$jeto ,ue define a 0m+/shirt0
return $
color5 Q&lueQ;
si+e5 QlargeQ
add9oKart5 function() $
in6entory.decrement(this);
cart.add(this);
%
%
%
);
-n este ejemploE el modulo m"/shirt es $reado. -ste depende de m"/cart y
m"/inventor". -n el dis$oE los ar$:ivos est&n estru$turados de la si'uiente formaN
my/cart.js
my/in6entory.js
my/shirt.js
0a fun$i*n Lue define m"/shirt no es llamada :asta Lue m"/cart y m"/inventor"
:ayan sido $ar'adasE y di$:a fun$i*n re$ibe $omo ar'umentos a los m*dulos $omo cart y
inventor". -l orden de los ar'umentos de la fun$i*n debe $oin$idir $on el orden en Lue
las dependen$ias se reLuieren en el ve$tor. -l objeto devuelto define el m*dulo m"/shirt.
)efiniendo los m*dulos de esta formaE m"/shirt no e7iste $omo un objeto 'lobalE ya Lue
m8ltiples m*dulos pueden e7istir en la p&'ina al mismo tiempo.
0os m*dulos no tienen Lue devolver un objetoO $ualLuier tipo de valor es permitido.
De!inicin de un mdulo /e1uireJS 1ue devuelve una !uncin
require.def(Qmy/titleQ;
2Qmy/dependency'Q; Qmy/dependency2Q3;
function(dep'; dep2) $
// devuelve una funcin para definir 0m+/title02
// 4ste devuelve o esta$lece
// el titulo de la ventana
return function(title) $
return title 4 (BindoB.title = title) 5 BindoB.title;
%
%
);
Solo un m*dulo debe ser reLuerido por ar$:ivo #avaS$ript.
1?.!.( Optimizar el +*di'o $on las Merramientas de 5eLuire#S
/na vez in$orporado 5eLuire#S para el manejo de dependen$iasE la optimiza$i*n del
$*di'o es muy f&$il. )es$ar'ue el paLuete de 5eLuire#S y $ol*Luelo en $ualLuier lu'arE
preferentemente fuera del &rea de desarrollo eb. %ara los prop*sitos de este ejemploE el
paLuete de 5eLuire#S esta ubi$ado en una $arpeta paralela al dire$torio webapp Ala $ual
$ontiene la p&'ina M3M0 y todos los ar$:ivos #avaS$ript de la apli$a$i*nB. 0a estru$tura de
dire$torios esN
requirejs/ (utili+ado para ejecutar las herramientas)
Be&app/app.html
Be&app/scripts/app.js
Be&app/scripts/require@jquery.js
Be&app/scripts/jquery.alpha.js
Be&app/scripts/jquery.&eta.js
0ue'oE en la $arpeta en donde se en$uentran re@uire%j@uer".js y app.jsE $rear un
ar$:ivo llamadoapp.build.js $on el si'uiente $ontenidoN
.rchivo de con!iguracin para las herramientas de optimi*acin de
/e1uireJS
$
app:ir5 Q../Q;
&aseSrl5 Qscripts/Q;
dir5 Q../../Be&app@&uildQ;
//=omentar la siguiente l-nea si se desea
//minificar el cdigo por el compilador
//en su modo 0simple0
optimi+e5 QnoneQ;

modules5 2
$
name5 QappQ
%
3
%
%ara utilizar la :erramientaE es ne$esario tener instalado #ava .. +losure +ompiler es
utilizado para la minifi$a$i*n del $*di'o Aen $aso Lue optimi*e+ EnoneE estF
$omentadoB.
%ara $omenzar a pro$esar los ar$:ivosE abrir una ventana de $omandosE diri'irse al
dire$torio webapp/scriptsy eje$utarN
M para sistemas que no son BindoBs
../../requirejs/&uild/&uild.sh app.&uild.js

M para sistemas BindoBs
..]..]requirejs]&uild]&uild.&at app.&uild.js
/na vez eje$utadoE el ar$:ivo app.js de la $arpeta webapp%build $ontendr& todo el
$*di'o de app.js m&s el de j@uer".alpha.js y j@uer".beta.js. Si se abre el
ar$:ivo app.html AtambiFn en la $arpeta webapp%buildB podr& notar Lue nin'una
peti$i*n se realiza para $ar'ar j@uer".alpha.js y j@uer".beta.js.
1?.( -jer$i$ios
1@.4.1 )rear un Mdulo 7ortlet
Abra el ar$:ivo /ejercicios/portlets.html en el nave'ador. 5eali$e el ejer$i$io
utilizando el ar$:ivo/ejercicios/js/portlets.js. -l ejer$i$io $onsiste en $rear una
fun$i*n $readora de portlet Lue utili$e el patr*n modularE de tal manera Lue el si'uiente
$*di'o fun$ioneN
var myTortlet = Tortlet($
title 5 'Kurry';
source 5 'data/html/curry.html';
initial.tate 5 'open' // or 'closed'
%);

myTortlet.Lelement.append9o('&ody');
+ada portlet deber& ser un div $on un tGtuloE un &rea de $ontenidoE un bot*n para
abrir/$errar el portletE un bot*n para removerlo y otro para a$tualizarlo. -l portlet devuelto
por la fun$i*n deber& tener la si'uiente A%6 p8bli$aN
myTortlet.open(); // fuer)a a a$rir
myTortlet.close(); // fuer)a a cerrar
myTortlet.toggle(); // alterna entre los estados a$ierto + cerrado
myTortlet.refresh(); // actuali)a el contenido
myTortlet.destroy(); // remueve el portlet de la pgina
myTortlet.set.ource('data/html/onions.html'); // cam$ia el cdigo
Capitulo NN
11 < -ventos %ersonalizados
11.1 Introduccin a los E.entos 7ersonalizados
3odos estamos familiarizados $on los eventos b&si$os U clic(E mouseoverE focusE
blurE submitE et$. U Lue sur'en a partir de la intera$$i*n del usuario $on el nave'ador.
0os eventos personalizados permiten $ono$er el mundo de la pro'rama$i*n orientada a
eventos Aen in'lFs event<driven pro'rammin'B. -n este $apGtuloE se utilizar& el sistema de
eventos personalizados de jQuery para $rear una simple apli$a$i*n de b8sLueda en
3itter.
-n un primer momento puede ser difG$il entender el reLuisito de utilizar eventos
personalizadosE ya Lue los eventos $onven$ionales permiten satisfa$er todas las
ne$esidades. Sin embar'oE los eventos personalizados ofre$en una nueva forma de pensar
la pro'rama$i*n en #avaS$ript. -n lu'ar de enfo$arse en el elemento Lue eje$uta una
a$$i*nE los eventos personalizados ponen la aten$i*n en el elemento en donde la a$$i*n va
a o$urrir. -ste $on$epto brinda varios benefi$iosN
los $omportamientos del elemento objetivo pueden ser eje$utados por diferentes
elementos utilizando el mismo $*di'oO
los $omportamientos pueden ser eje$utados en m8ltiplesE similares elementos objetivos a
la vezO
los $omportamientos son aso$iados de forma m&s $lara $on el elemento objetivoE :a$iendo
Lue el $*di'o sea m&s f&$il de leer y mantener.
/n ejemplo es la mejor forma de e7pli$ar el asunto. Supon'a Lue posee una l&mpara
in$andes$ente en una :abita$i*n de una $asa. 0a l&mpara a$tualmente esta en$endida. 0a
misma es $ontrolada por dos interruptores de tres posi$iones y un $lapper Ainterruptor
a$tivado por aplausosBN
<div class=QroomQ id=Q(itchenQ>
<div class=Qlight&ul& onQ></div>
<div class=QsBitchQ></div>
<div class=QsBitchQ></div>
<div class=QclapperQ></div>
</div>
-je$utando el $lapper o al'uno de los interruptoresE el estado de la lampara $ambia. A los
interruptores o al$lapper no le interesan si la l&mpara esta prendida o apa'adaE tan solo
Luieren $ambiar su estado
Sin la utiliza$i*n de eventos personalizadosE es posible es$ribir la rutina de la si'uiente
maneraN
L('.sBitch; .clapper').clic((function() $
var Llight = L(this).parent().find('.light&ul&');
if (Llight.hasKlass('on')) $
Llight.remo6eKlass('on').addKlass('off');
% else $
Llight.remo6eKlass('off').addKlass('on');
%
%);
%or otro ladoE utilizando eventos personalizadosE el $*di'o Lueda asGN
L('.light&ul&').on('change.tate'; function(e) $
var Llight = L(this);
if (Llight.hasKlass('on')) $
Llight.remo6eKlass('on').addKlass('off');
% else $
Llight.remo6eKlass('off').addKlass('on');
%
%);

L('.sBitch; .clapper').clic((function() $
L(this).parent().find('.light&ul&').trigger('change.tate');
%);
Al'o importante :a su$edidoN el $omportamiento de la l&mpara se :a movidoE antes estaba
en los interruptores y en el $lapperE a:ora se en$uentra en la misma l&mpara.
3ambiFn es posible :a$er el ejemplo un po$o m&s interesante. Supon'a Lue se :a a"adido
otra :abita$i*n a la $asaE junto $on un interruptor 'eneralE $omo se muestra a
$ontinua$i*nN
<di6 class=QroomQ id=Q(itchenQ>
<di6 class=Qlight&ul& onQ></di6>
<di6 class=QsBitchQ></di6>
<di6 class=QsBitchQ></di6>
<di6 class=QclapperQ></di6>
</di6>
<di6 class=QroomQ id=Q&edroomQ>
<di6 class=Qlight&ul& onQ></di6>
<di6 class=QsBitchQ></di6>
<di6 class=QsBitchQ></di6>
<di6 class=QclapperQ></di6>
</di6>
<di6 id=QmasterNsBitchQ></di6>
Si e7iste al'una l&mpara prendida en la $asaE es posible apa'arlas a travFs del interruptor
'eneralE de i'ual forma si e7isten lu$es apa'adasE es posible prenderlas $on di$:o
interruptor. %ara realizar esta tareaE se a're'an dos eventos personalizados m&s a la
l&mparaN turn9n y turn9ff. A travFs de una l*'i$a en el eventochange$tate se de$ide
LuF evento personalizado utilizarN
L('.light&ul&')
.on('change.tate'; function(e) $
var Llight = L(this);
if (Llight.hasKlass('on')) $
Llight.trigger('turnCff');
% else $
Llight.trigger('turnCn');
%
%)
.on('turnCn'; function(e) $
L(this).remo6eKlass('off').addKlass('on');
%)
.on('turnCff'; function(e) $
L(this).remo6eKlass('off').addKlass('on');
%);

L('.sBitch; .clapper').clic((function() $
L(this).parent().find('.light&ul&').trigger('change.tate');
%);

L('MmasterNsBitch').clic((function() $
if (L('.light&ul&.on').length) $
L('.light&ul&').trigger('turnCff');
% else $
L('.light&ul&').trigger('turnCn');
%
%);
2ote $omo el $omportamiento del interruptor 'eneral se :a vin$ulado al interruptor
'eneral mientras Lue el $omportamiento de las l&mparas pertene$e a las l&mparas.
Nota
Si esta a$ostumbrado a la pro'rama$i*n orientada a objetosE puede resultar 8til
pensar de los eventos personalizados $omo mFtodos de objetos. -n tFrminos
'eneralesE el objeto al Lue pertene$e el mFtodo se $rea a partir del sele$tor
jQuery. 9in$ular el evento personalizado change$tate a todos los elementos$
(G.lightH) es similar a tener una $lase llamada =ight $on un mFtodo
change$tateE y lue'o instan$iar nuevos objetos =ight por $ada elemento.
/ecapitulacinL ( !n( on&(!n(trigger
-n el mundo de los eventos personalizadosE e7isten dos mFtodos importantes de jQueryN
$.fn.on y$.fn.trigger. -n el $apGtulo dedi$ado a eventos se e7pli$* la utiliza$i*n de
estos dos mFtodos para trabajar $on eventos del usuarioO en este $apGtulo es importante
re$ordar 2 puntosN
el mFtodo $.fn.on toma $omo ar'umentos un tipo de evento y una fun$i*n $ontroladora
de evento. Op$ionalmenteE puede re$ibir informa$i*n aso$iada al evento $omo se'undo
ar'umentoE desplazando $omo ter$er ar'umento a la fun$i*n $ontroladora de evento.
+ualLuier informa$i*n pasada estar& disponible a la fun$i*n $ontroladora a travFs de la
propiedad data del objeto del evento. A su vezE la fun$i*n $ontroladora re$ibe el objeto del
evento $omo primer ar'umentoO
el mFtodo $.fn.trigger toma $omo ar'umentos el tipo de evento y op$ionalmenteE
puede tomar un ve$tor $on valores. -stos valores ser&n pasados a la fun$i*n $ontroladora
de eventos $omo ar'umentos lue'o del objeto del evento.
A $ontinua$i*n se muestra un ejemplo de utiliza$i*n de $.fn.on y $.fn.trigger en
donde se utiliza informa$i*n personalizada en ambos $asosN
L(document).on('myKustom>6ent'; $ foo 5 '&ar' %; function(e; arg'; arg2) $
console.log(e.data.foo); // '$ar'
console.log(arg'); // '$im'
console.log(arg2); // '$a)'
%);

L(document).trigger('myKustom>6ent'; 2 '&im'; '&a+' 3);
11.1.1 $n Ejemplo de Aplicacin
%ara demostrar el poder de los eventos personalizadosE se desarrollar& una simple
:erramienta para bus$ar en3itter. )i$:a :erramienta ofre$er& varias maneras para Lue el
usuario reali$e una b8sLuedaN in'resando el tFrmino a bus$ar en una $aja de te7to o
$onsultando los Htemas de modaI de 3itter.
0os resultados de $ada tFrmino se mostrar&n en un $ontenedor de resultadosO di$:os
resultados podr&n e7pandirseE $olapsarseE refres$arse y removerseE ya sea de forma
individual o $onjunta.
-l resultado final de la apli$a$i*n ser& el si'uienteN
)igura NN(N( a aplicacin !inali*ada
0a apli$a$i*n finalizada
11.1.1.1 Iniciacin
Se empieza $on un M3M0 b&si$oN
<h'>9Bitter .earch</h'>
<input type=Q&uttonQ id=QgetNtrendsQ
6alue=Q=oad 9rending 9ermsQ />

<form>
<input type=Qte<tQ class=QinputNte<tQ
id=QsearchNtermQ />
<input type=Qsu&mitQ class=QinputNsu&mitQ
6alue=Q?dd .earch 9ermQ />
</form>

<di6 id=QtBitterQ>
<di6 class=Qtemplate resultsQ>
<h2>.earch Desults for
<span class=QsearchNtermQ></span></h2>
</di6>
</di6>
-l M3M0 posee un $ontenedor AVtitterB para el id'etE una plantilla para los resultados
Ao$ulto $on +SSB y un simple formulario en donde el usuario puede es$ribir el tFrmino a
bus$ar.
-7isten dos tipos de elementos en los $uales a$tuarN los $ontenedores de resultados y el
$ontenedor 3itter.
0os $ontenedores de resultados son el $oraz*n de la apli$a$i*n. Se $rear& una e7tensi*n
para preparar $ada $ontenedor una vez Lue Fste se a're'a al $ontenedor 3itter. Adem&sE
entre otras $osasE la e7tensi*n vin$ular& los eventos personalizados por $ada $ontenedor y
a"adir& en la parte superior dere$:a de $ada $ontenedor botones Lue eje$utar&n a$$iones.
+ada $ontenedor de resultados tendr& los si'uientes eventos personalizadosN
refres:
Se"ala Lue la informa$i*n del $ontenedor se esta a$tualizando y dispara la peti$i*n
Lue bus$a los datos para el tFrmino de b8sLueda.
populate
5e$ibe la informa$i*n #SO2 y la utiliza para rellenar el $ontenedor.
remove
5emueve el $ontenedor de la p&'ina lue'o de Lue el usuario $onfirme la a$$i*n. )i$:a
$onfirma$i*n puede omitirse si se pasa true $omo se'undo ar'umento del
$ontrolador de evento. -l evento adem&s remueve el tFrmino aso$iado $on el
$ontenedor de resultados del objeto 'lobal Lue $ontiene los tFrminos de b8sLueda.
$ollapse
A"ade una $lase al $ontenedorE la $ual o$ultar& el resultado a travFs de +SS. Adem&s
$ambiar& el bot*n de H+olapsarI a H-7pandirI.
e7pand
5emueve la $lase del $ontenedor Lue a"ade el evento $ollapse. Adem&s $ambiar& el
bot*n de H-7pandirI a H+olapsarI.
Adem&sE la e7tensi*n es responsable de a"adir los botones de a$$iones al $ontenedorE
vin$ulando un eventoclic( a $ada bot*n y utilizando la $lase de $ada Gtem para
determinar LuF evento personalizado ser& eje$utado en $ada $ontenedor de resultados.
L.fn.tBitterDesult = function(settings) $
return this.each(function() $
var Lresults = L(this);
Lactions = L.fn.tBitterDesult.actions =
L.fn.tBitterDesult.actions ,,
L.fn.tBitterDesult.create?ctions();
La = Lactions.clone().prepend9o(Lresults);
term = settings.term;

Lresults.find('span.searchNterm').te<t(term);

L.each(
2'refresh'; 'populate'; 'remo6e'; 'collapse'; 'e<pand'3;
function(i; e6) $
Lresults.&ind(
e6;
$ term 5 term %;
L.fn.tBitterDesult.e6ents2e63
);
%
);

// utili)a la clase de cada accin para determinar
// ,ue evento se ejecutar en el panel de resultados
La.find('li').clic((function() $
// pasa el elemento EliF cliceado en la funcin
// para ,ue se pueda manipular en caso de ser necesario
Lresults.trigger(L(this).attr('class'); 2 L(this) 3);
%);
%);
%;

L.fn.tBitterDesult.create?ctions = function() $
return L('<ul class=QactionsQ />').append(
'<li class=QrefreshQ>Defresh</li>' "
'<li class=Qremo6eQ>Demo6e</li>' "
'<li class=QcollapseQ>Kollapse</li>'
);
%;

L.fn.tBitterDesult.e6ents = $
refresh 5 function(e) $
// indica ,ue los resultados se estan actuali)ando
var Lthis = L(this).addKlass('refreshing');

Lthis.find('p.tBeet').remo6e();
Lresults.append('<p class=QloadingQ>=oading ...</p>');

// o$tiene la informacin de TKitter en formato jsonp
L.getY.C)(
'http5//search.tBitter.com/search.json4q=' "
escape(e.data.term) " '-rpp=#-call&ac(=4';
function(json) $
Lthis.trigger('populate'; 2 json 3);
%
);
%;

populate 5 function(e; json) $
var results = json.results;
var Lthis = L(this);

Lthis.find('p.loading').remo6e();

L.each(results; function(i;result) $
var tBeet = '<p class=QtBeetQ>' "
'<a href=Qhttp5//tBitter.com/' "
result.fromNuser "
'Q>' "
result.fromNuser "
'</a>5 ' "
result.te<t "
' <span class=QdateQ>' "
result.createdNat "
'</span>' "
'</p>';
Lthis.append(tBeet);
%);

// indica ,ue los resultados
// +a se han actuali)ado
Lthis.remo6eKlass('refreshing');
%;

remo6e 5 function(e; force) $
if (
0force --
0confirm('Demo6e panel for term ' " e.data.term " '4')
) $
return;
%
L(this).remo6e();

// indica ,ue +a no se tendr
// un panel para el trmino
searchNterms2e.data.term3 = *;
%;

collapse 5 function(e) $
L(this).find('li.collapse').remo6eKlass('collapse')
.addKlass('e<pand').te<t('><pand');

L(this).addKlass('collapsed');
%;

e<pand 5 function(e) $
L(this).find('li.e<pand').remo6eKlass('e<pand')
.addKlass('collapse').te<t('Kollapse');

L(this).remo6eKlass('collapsed');
%
%;
-l $ontenedor 3itterE posee solo dos eventos personalizadosN
'et5esults
5e$ibe un tFrmino de b8sLueda y $omprueba si ya no e7iste un $ontenedor de
resultados para di$:o tFrmino. -n $aso de no e7istirE a"ade un $ontenedor utilizando
la plantilla de resultadosE lo $onfi'ura utilizando la e7tensi*n
$.fn.twitter?esult Amostrada anteriormenteB y lue'o eje$uta el evento
refresh $on el fin de $ar'ar $orre$tamente los resultados. FinalmenteE 'uarda el
tFrmino bus$ado para no tener volver a pedir los datos sobre la b8sLueda.
'et3rends
+onsulta a 3itter el listado de los 1? primeros HtFrminos de modaIE intera$t8a $on
ellos y eje$uta el eventoget?esults por $ada unoE de tal modo Lue a"ade un
$ontenedor de resultados por $ada tFrmino.
9in$ula$iones en el $ontenedor 3itterN
L('MtBitter')
.on('getDesults'; function(e; term) $
// se comprue$a ,ue +a no eCista una caja para el trmino
if (0searchNterms2term3) $
var Lthis = L(this);
var Ltemplate = Lthis.find('di6.template');

// reali)a una copia de la plantilla
// + la inserta como la primera caja de resultados
Lresults = Ltemplate.clone().
remo6eKlass('template').
insert/efore(Lthis.find('di65first')).
tBitterDesult($
'term' 5 term
%);

// carga el contenido utili)ando el evento personali)ado 0refresh0
// vinculado al contenedor de resultados
Lresults.trigger('refresh');
searchNterms2term3 = ';
%
%)
.on('get9rends'; function(e) $
var Lthis = L(this);
L.getY.C)('http5//api.tBitter.com/'/trends/'.json4call&ac(=4'; function(json) $
var trends = json2*3.trends;
L.each(trends; function(i; trend) $
Lthis.trigger('getDesults'; 2 trend.name 3);
%);
%);
%);
Masta a:oraE se :a es$rito una 'ran $antidad de $*di'o Lue no realiza nadaE lo $ual no esta
mal. Se :an espe$ifi$ado todos los $omportamientos Lue se desean para los elementos
n8$leos y se :a $reado un s*lido mar$o para la $rea$i*n r&pida de la interfaz.
A $ontinua$i*nE se $one$ta la $aja de b8sLueda y el bot*n para $ar'ar los H3emas de modaI.
-n la $aja de te7toE se $aptura el tFrmino in'resado y se pasa al mismo tiempo Lue se
eje$uta el evento get?esults. %or otro ladoE :a$iendo $li$= en el bot*n para $ar'ar los
H3emas de modaIE se eje$uta el evento get/rendsN
L('form').su&mit(function(e) $
e.pre6ent:efault();
var term = L('MsearchNterm').6al();
L('MtBitter').trigger('getDesults'; 2 term 3);
%);

L('MgetNtrends').clic((function() $
L('MtBitter').trigger('get9rends');
%);
A"adiendo botones $on un 6) apropiadoE es posible removerE $olapsarE e7pandir y
refres$ar todos los $ontenedores de resultados al mismo tiempo. %ara el bot*n Lue
remueve el $ontenedorE notar Lue se esta pasandotrue al $ontrolador del evento $omo
se'undo ar'umentoE indi$ando Lue no se desea una $onfirma$i*n del usuario para
remover el $ontenedor.
L.each(2'refresh'; 'e<pand'; 'collapse'3; function(i; e6) $
L('M' " e6).clic((function(e) $ L('MtBitter di6.results').trigger(e6); %);
%);

L('Mremo6e').clic((function(e) $
if (confirm('Demo6e all results4')) $
L('MtBitter di6.results').trigger('remo6e'; 2 true 3);
%
%);
11.1.1.2 +on$lusi*n
0os eventos personalizados ofre$en una nueva manera de pensar el $*di'oN ellos ponen el
Fnfasis en el objetivo de un $omportamientoE no en el elemento Lue lo a$tiva. Si se toma el
tiempo desde el prin$ipio para e7pli$ar las piezas de su apli$a$i*nE asG $omo los
$omportamientos Lue esas piezas ne$esitan e7:ibirE los eventos personalizados proveen
una manera poderosa para H:ablarI $on esas piezasE ya sea de una en una o en masa.
/na vez Lue los $omportamientos se :an des$riptoE se $onvierte en al'o trivial eje$utarlos
desde $ualLuier lu'arE lo Lue permite la r&pida $rea$i*n y e7perimenta$i*n de op$iones de
interfaz. FinalmenteE los eventos personalizados tambiFn permiten mejorar la le$tura del
$*di'o y su mantenimientoE :a$iendo $lara la rela$i*n entre un elemento y su
$omportamiento.
%uede ver la apli$a$i*n $ompleta en los ar$:ivos demos/custom%events/custom%
events.html ydemos/custom%events/js/custom%events.js del material Lue
$omponen este libro.
Capitulo N2
12 < Fun$iones y eje$u$iones diferidas a travFs del objeto
$.Deferred
12.1 Introduccin
A partir de la versi*n 1., de jQueryE la bibliote$a introdujo una nueva utilidadN -l objeto
diferido $.Deferred Aen in'lFs )eferred Obje$tB. -ste objeto introdu$e nuevas formas
para la invo$a$i*n y eje$u$i*n de las fun$iones de devolu$i*n A$allba$=sBE permitiendo
$rear apli$a$iones m&s robustas y fle7ibles. %ara m&s detalles sobre$.DeferredE puede
$onsultar :ttpN//api.jLuery.$om/$ate'ory/deferred<obje$t/.
12.2 -l objeto diferido y Aja7
-l $aso m&s $om8n en donde se puede apre$iar la utilidad del objeto diferido es en el
manejo de las fun$iones de devolu$i*n en peti$iones Aja7.
Se'8n se pudo apre$iar en el $apGtulo dedi$adoE una manera de invo$ar una peti$i*n Aja7
esN
%anera tradicional de utili*ar el m"todo $.ajax
L.aja<($
// la M;" para la peticin
url 5 'post.php';

// funcines de devolucin a ejecutar
// en caso ,ue la peticin ha+a sido
// satisfactoria, con error +/o completada
success 5 function(data) $
alert('Tetici8n reali+ada satisfactoriamente');
%;
error 5 function(jqXAD; status; error) $
alert(':isculpe; e<isti8 un pro&lema');
%;
complete 5 function(jqXAD; status) $
alert('Tetici8n reali+ada');
%
%);
+omo se puede observarE las fun$iones de devolu$i*n son $onfi'uradas dentro del mismo
objeto $.aja). -sta manera es in$omoda y po$o fle7ible ya Lue no permite desacoplar
las !unciones de devolucin de la misma peticin .jax. [ en 'randes apli$a$iones
esto puede lle'ar a ser un problema.
-l objeto diferido nos permite rees$ribir el $*di'o anterior de la si'uiente maneraN
El objeto di!erido en una peticin .jax
// dentro de una varia$le se define
// la configuracin de la peticin ajaC
var aja< = L.aja<($
url 5 'post.php'
%);

// a travs del mtodo done&' ejecutamos
// la funcin de devolucin satisfactoria &sucess'
aja<.done(function()$
alert('Tetici8n reali+ada satisfactoriamente');
%);

// a travs del mtodo fail&' ejecutamos
// la funcin de devolucin de error &error'
aja<.fail(function()$
alert(':isculpe; e<isti8 un pro&lema');
%);

// a travs del mtodo alKa+s&' ejecutamos
// la funcin de devolucin de peticin completada &complete'
aja<.alBays(function()$
alert('Tetici8n reali+ada');
%);
A travFs de los mFtodos deferred.doneE deferred.fail y deferred.alwa"s es
posible desa$oplar las fun$iones de devolu$i*n de la misma peti$i*n Aja7E permitiendo un
manejo m&s $omodo de las mismas.
2otar Lue en en nin'8n momento se llama al objeto diferido $.Deferred. -sto es porLue
jQuery ya lo in$orpora impli$itamente dentro del manejo del objeto $.aja). M&s adelante
se e7pli$ar& $omo utilizar al objeto $.Deferred de manera e7plG$ita.
)e la misma forma es posible $rear $olas de fun$iones de devolu$i*n o atarlas a diferentes
l*'i$as/a$$ionesN
Colas de !unciones de devolucin en una peticin .jax
// definicin de la peticin 5jaC
var aja< = L.aja<($
url 5 'post.php'
%);

// primera funcin de devolucin a ejecutar
aja<.done(function()$
alert('Trimera funci8n de de6oluci8n en caso satisfactorio');
%);

// segunda funcin de devolucin a ejecutar
// inmediatamente despus de la primera
aja<.done(function()$
alert('.egunda funci8n de de6oluci8n en caso satisfactorio');
%);

// si el usuario hace clic en Gelement se
// agrega una tercera funcin de devolucin
L('Melement').clic((function()$

aja<.done(function()$
alert('9ercera funci8n de de6oluci8n si el usuario hace clic(');
%);

%);

// en caso ,ue eCista un error se define otra
// funcin de devolucin
aja<.fail(function()$
alert(':isculpe; e<isti8 un pro&lema');
%);
Al eje$utarse la peti$i*n Aja7E y en $aso de Lue Fsta :aya sido satisfa$toriaE se eje$utan dos
fun$iones de devolu$i*nE una detr&s de la otra. Sin embar'o si el usuario :a$e $li$= en
.element se a're'a una ter$era fun$i*n de devolu$i*nE la $ual tambiFn se eje$uta
inmediatamenteE sin volver a realizar la peti$i*n Aja7. -sto es porLue el objeto diferido
ALue se en$uentra impli$itamente en la variable aja)B ya tiene informa$i*n aso$iada sobre
Lue la peti$i*n Aja7 se realiz* $orre$tamente.
12.2.1 deferred.then
Otra manera de utilizar los mFtodos deferred.done y deferred.fail es a travFs de
deferred.thenE el $ual permite definir en un mismo bloLue de $*di'o las fun$iones de
devolu$i*n a su$eder en los $asos satisfa$torios y erroneos.
2tili*acin del m"todo deferred.then
// definicin de la peticin 5jaC
var aja< = L.aja<($
url 5 'post.php'
%);

// el mtodo espera dos funciones de devolucin
aja<.then(

// la primera es la funcin de devolucin satisfactoria
function()$
alert('Tetici8n reali+ada satisfactoriamente');
%;

// la segunda es la funcin de devolucin erronea
function()$
alert(':isculpe; e<isti8 un pro&lema');
%

);
12.! +rea$i*n de objetos diferidos $on $.Deferred
AsG $omo es posible desa$oplar las fun$iones de devolu$i*n en una peti$i*n Aja7E tambiFn
es posible realizarlo en otras fun$iones utilizando de manera e7plG$ita el objeto
$.Deferred.
%or ejemploE una fun$i*n Lue verifi$a si un n8mero es parE de la manera tradi$ional puede
es$ribirse de la si'uiente maneraN
)uncin sin utili*ar el objeto $.Deferred
// funcin ,ue calcula si un n%mero entero es par o impar
var is>6en = function(num&er) $

if (num&erZ2 == *)$
return true;
% else $
return false;
%

%

// si es par registra un mensaje,
// en caso contrario registra otro
if (is>6en(2))$
console.log('>s par');
% else $
console.log('>s impar');
%
/tilizando el objeto $.DeferredE el mismo ejemplo puede rees$ribirse de la si'uiente
formaN
)uncin utili*ando el objeto $.Deferred
// funcin ,ue calcula si un n%mero entero es par o impar
var is>6en = function(num&er) $

// guarda en una varia$le al o$jeto R2Deferred&'
var dfd = L.:eferred();

// si es par, resuelve al o$jeto utili)ando deferred2resolve,
// caso contrario, lo recha)a utili)ando deferred2reject
if (num&erZ2 == *)$
dfd.resol6e();
% else $
dfd.reject();
%

// devuelve al o$jeto diferido con su estado definido
return dfd.promise();

%

// con deferred2then se manejan las funciones de devolucin
// en los casos ,ue el numero sea par o impar
is>6en(2).then(

// la primera es la funcin de devolucin satisfactoria
function()$
console.log('>s par');
%;

// la segunda es la funcin de devolucin erronea
function()$
console.log('>s impar');
%

);
0os mFtodos deferred.resolve y deferred.reject permiten de!inir el estado
interno del objeto$.Deferred(). -sta defini$i*n es permanente# es decir# no es
posible modi!icarla despu"s y es lo Lue permite manejar el $omportamiento y
eje$u$i*n de las fun$iones de devolu$i*n posteriores para $ada uno de los $asos.
2otar Lue la fun$i*n isven devuelve el mFtodo deferred.promise. -l mismo es una
versi*n del objeto diferidoE pero Lue s*lo permite leer su estado o a"adir nuevas fun$iones
de devolu$i*n.
Nota
-n los ejemplos Lue utilizaban Aja7 mostrados anteriormenteE los mFtodos
deferred.resolve ydeferred.reject son llamados de manera interna
por jQuery dentro de la $onfi'ura$i*n sucess yerror de la peti$i*n. %or eso
mismos se de$Ga Lue el objeto diferido estaba in$orporado impli$itamente
dentro del objeto $.aja).
0os mFtodos deferred.resolve y deferred.reject adem&s permiten devolver
valores para ser utilizados por las fun$iones de devolu$i*n.
)uncin con deferred.resolve & deferred.reject devolviendo valores
reutili*ables
// funcin ,ue calcula si un numero entero es par o impar
var is>6en = function(num&er) $

var dfd = L.:eferred();

// resuelve o recha)a al o$jeto utili)ando
// + devuelve un teCto con el resultado
if (num&erZ2 == *)$
dfd.resol6e('>l n^mero ' " num&er " ' es par');
% else $
dfd.reject('>l n^mero ' " num&er " ' es impar');
%

// devuelve al o$jeto diferido con su estado definido
return dfd.promise();

%

is>6en(2).then(

function(result)$
console.log(result); // ;egistra '4l n%mero 2 es par'
%;

function(result)$
console.log(result);
%

);
Nota
-s posible determinar el estado de un objeto diferido a travFs del mFtodo
deferred.state. -l mismo devuelve un strin' $on al'uno de estos tres
valoresN pendingE resolved o rejected. %ara m&s detalles sobre
deferred.stateE puede $onsultar :ttpN//api.jLuery.$om/deferred.state/.
12.3.1 deferred.pipe
-7isten $asos en Lue se ne$esita modifi$ar el estado de un objeto diferido o filtrar la
informa$i*n Lue viene aso$iada. %ara estos $asos e7iste deferred.pipe. Su
fun$ionamiento es similar a deferred.thenE $on la diferen$ia Lue deferred.pipe
devuelve un nuevo objeto diferido modifi$ado a travFs de una fun$i*n interna.
)uncin !iltrando valores utili*ando deferred.pipe
// funcin ,ue calcula si un n%mero entero es par o impar
var is>6en = function(num&er) $

var dfd = L.:eferred();

if (num&erZ2 == *)$
dfd.resol6e(num&er);
% else $
dfd.reject(num&er);
%

return dfd.promise();

%

// vector con una serie de n%meros pares e impares
var num&ers = 2*; 2; G; '*; #; I; '23;

// a travs de deferred2pipe se pregunta si n%mero se encuentra
// dentro del vector num$ers
is>6en(2).pipe(

function(num&er)$

// crea un nuevo o$jeto diferido
var dfd = L.:eferred();

if(L.in?rray(num&er; num&ers) 0== @')$
dfd.resol6e();
% else $
dfd.reject();
%

// devuelve un nuevo o$jeto diferido
return dfd.promise();

%

).then(

function()$
// al estar dentro del vector num$ers + ser par,
// se registra este mensaje
console.log('>l n^mero es par y se encuentra dentro de num&ers');
%;

function()$
console.log('>l n^mero es impar o no se encuentra dentro de num&ers');
%

);
%ara m&s detalles sobre deferred.pipeE puede $onsultar
:ttpN//api.jLuery.$om/deferred.pipe/.
12.!.2 $.when
-l mFtodo $.when permite eje$utar fun$iones de devolu$i*nE $uando uno o m&s objetos
diferidos posean al'un estado definido.
/n $aso $om8n de utiliza$i*n de $.when es $uando se Luiere verifi$ar Lue dos peti$iones
Aja7 separadas se :an realizado.
2tili*acin de $.when
// primera peticin ajaC
var comments = L.aja<($
url 5 '/echo/json/'
%);

// segunda peticin ajaC
var 6alidation = L.aja<($
url 5 '/echo/json/'
%);
// cuando las dos peticiones sean reali)adas
// ejecuta alguna funcin de devolucin definida
// dentro de deferred2then
L.Bhen(comments; 6alidation).then(
function()$
alert('Teticiones reali+adas');
%;
function()$
alert(':isculpe; e<isti8 un pro&lema');
%
);
%ara m&s detalles sobre $.whenE puede $onsultar :ttpN//api.jLuery.$om/jQuery.:en/.

Anda mungkin juga menyukai