You are on page 1of 193

JavaScript

Edición 2012

Astor de Caso Parra

■ M U L TIM E D IA *
G U ÍA S P R Á C T IC A S

"Aunque los perros no programan;


Yembo, form as parte de esta guía."

Reservados todos los derechos. El contenido


de esta obra está protegido por la Ley, que
establece penas de prisión y;/o multas, además
de las correspondientes indemnizaciones por.
daños y perjuicios, para quienes reproduje- ’ ; ;
ren, plagiaren, distribuyeren o comunica­
ren públicamente, en todo o en parte, una
obra literaria, artística o científica, o su
transformación, interpretación o ejecución
artística fijada en cualquier tipo de soporte o
comunicada a través de cualquier medio, sin
la preceptiva autorización.

© EDICIONES ANAYA MULTIMEDIA (GRUPO ANAYA, S.A.), 2012


Juan Ignacio Luca de Tena, 15. 28027 Madrid
Depósito legal: M.38.836-2011
ISBN: 978-84-415-3048-5
Printed in Spain
Impreso en: Closas-Orcoyen, S.L.
Agradecimientos
Gracias a todos los lectores de la anterior edición porque van
a hacer posible que futuros nuevos lectores puedan aprender
tanto como ellos. También quiero dar las gracias a Anaya por Indice
confiar en mí de nuevo para desarrollar esta nueva edición.
Por supuesto, gracias a m i familia y amigos más cercanos
por apoyarme tanto o más que la vez anterior.

Introducción........................................................................................ ..
¿De qué trata este libro?............................................................... 15
Navegadores W e b ..........................................................................15
Herramientas para programar en Jav aScrip t....................... 17
Notas fin ales.....................................................................................\ j
Cómo usar este lib ro ........................................................................... 19

Conocimientos p rev io s................................................................. 20


Estructura del libro.........................................................................20
Código fuente...................................................................................20

1. Introducción a Jav aScrip t.............................................................21


1.1. Versiones de JavaScript y los navegadores................... 23
1.2. Integración con H TM L......................................................... 25
1.3. Sintaxis del lenguaje.............................................................. 26
1.3.1. M ayúsculas y m inúsculas.......................................27
1.3.2. C om entarios................................................................ 27
1.3.3. Separación de instrucciones....................................28
1.4. Navegadores sin soporte JavaScrip t................................ 29
2 . Variables, tipos de datos y expresiones regulares................31
2 .1 . V ariables....................................................................................31
2 . 1 . 1 . Declaración de v ariab les......................................... 32
2.1.2. ¿Y las constantes?.......................................................33
2 .2 . Tipos de d atos..........................................................................34
2 .2 . 1 . N úm eros........................................................................35
5.2.1. Definición de parám etros..................................... 96
2.2.2. L ógicos........................................................................36 5.2.2. M últiples parám etros............................................. 98
2.2.3. Cadenas.......................................................................37 5.2.3. Parámetros obligatorios y opcionales.............. 99
2.2.4. O b jeto s................. ......................................................39 5.3. Valores de retorn o...............................................................101
2.2.5. Valores especiales....................................................40 5.3.1. M últiples valores de re to rn o ............................ 103
2.3. Expresiones regulares...........................................................41 5.4. Funciones predefinidas..................................................... 104
2.3.1. Escribir una expresión reg u la r.............................41 5.4.1. Función N u m ber................................................... 104
2.3.2. Usar paréntesis dentro de una expresión 5.4.2. Función String.........................................................105
regular...........................................................................47 5.4.3. Función isN aN ........................................................105
2.3.3. M odificadores............................................................ 48 5.4.4. Función isF in ite..................................................... 106
2.4. Expresiones regulares útiles............................................... 49 5.4.5. Función parselnt.................................................... 107
5.4.6. Función parseFloat................................................109
3. Operadores y conversión entre tipos.........................................51
5.4.7. Función escape....................................................... 109
3.1. Operadores en JavaScript....................................................51 5.4.8. Función unescape..................................................110
3.1.1. Operador de asignación..........................................51 5.4.9. Función ev al............................................................ 111
3.1.2. Operadores aritm éticos...........................................51 5.5. Ámbito o alcance de las variables................................. 112
3.1.3. Operador sobre cadenas......................................... 57 5.5.1. Ámbito lo cal............................................................112
3.1.4. Operadores ló g ico s.................................................. 58 5.5.2. Ámbito g lo b al........................................................ 114
3.1.5. Operadores condicionales 5.5.3. Prioridad de las variables................................... 115
o de com paración......................................... 59
6 . Programación orientadaa objetos........................................... 117
3.1.6. Operadores sobre bits o b in arios.........................62
3.1.7. Operadores especiales.............................................71 6.1. Definición de un objeto (constructor).......................... 118
3.1.8. Precedencia de los operadores............................. 74 6.2. Trabajar con objetos............................................................ 119
3.2. Conversión entre tipos.........................................................75 6.2.1. Definición de propiedades en un objeto......120
3.2.1. Conversión im plícita................................................75 6.2.2. Definición de m étodos......................................... 121
3.2.2. Conversión exp lícita................................................76 6.3. Estructuras de manipulación de o b jeto s..................... 124
6.3.1. Sentencia for - in .................................................... 125
4. Estructuras de control...................................................................79 6.3.2. Sentencia w ith........................................................ 126
4.1. Estructuras condicionales...................................................80
7. Objetos de Jav aScrip t..................................................................129
4.1.1. Sentencia if - e ls e ...................................................... 80
4.1.2. Sentencia switch - case............................................ 83 7.1. Objetos en v oltorio.............................................................. 129
4.2. Estructuras de b u cle............................................................. 86 7.1.1. Objeto Boolean....................................................... 129
4.2.1. Sentencia for............................................................... 86 7.1.2. Objeto N um ber...................................................... 131
4.2.2. Sentencia do - w h ile................................................ 89 7.1.3. Objeto S trin g ...........................................................134
4.2.3. Sentencia w h ile......................................................... 90 7.2. Objeto A rray......................................................................... 139
4.2.4. Sentencias break y continué.................................. 91 7.2.1. Constructor.............................................................. 139
4.3. Estructuras de manipulación de ob jetos...................... 92 7.2.2. Trabajar con un array........................................... 140
7.2.3. Propiedades y m étodos.......................................145
5. Funciones......................................................................................... 93 7.2.4. Arrays m ultidim ensionales............................... 149
5.1. Declaración de funciones................................................... 93 7.2.5. Arrays en elementos de JavaScript..................156
5.2. Parám etros..............................................................................96
9
8
7.3. Objeto D ate.......................................................................... 159 9. Form ularios................................................................................. 201
7.3.1. Constructor...............................................................160
7.3.2. Propiedades y m étod os........................................161 9.1. Form ularios en H T M L ....................................................... 201
7.3.3. Trabajar con fechas................................................ 164 9.1.1. Form ulario................................................................. 201
7.4. Objeto M ath .........................................................................167 9.1.2. Campos de entrada de d atos...............................204
7.4.1. Constructor...............................................................167 9.1.3. Campos de selección de datos............................ 207
7.4.2. Propiedades y m étod os......................................167 9.1.4. Botones........................................................................210
7.5. Objeto RegExp...................................................................170 9.1.5. Resumen de tipos de elementos <INPUT>.... 213
7.5.1. Constructor...............................................................170 9.2. Formularios en JavaScrip t................................................ 214
7.5.2. Propiedades y m étod os........................................171 9.2.1. Form ulario.................................................................214
9.2.2. Campos de entrada de d ato s.............................. 217
8 . Objetos del navegador (D O M )..............................................175 9.2.3. Campos de selección de datos............................ 221
8.1. Compatibilidad entre navegad ores...........................175 9.2.4. Botones........................................................................226
8.2. Objeto w indow ..................................................................176 9.2.5. Resumen de tipos de cam p os............................. 228
8 .2 .1 . Colecciones de objetos.......................................176 9.3. Validar datos de un form ulario...................................... 228
8.2.2. Propiedades...........................................................177 9.3.1. Definir form ulario.................................................. 229
8.2.3. M étod os................................................................. 179 9.3.2. Validación del nom bre de usuario.................... 230
8.3. Objeto n avigator............................................................... 185 9.3.3. Validación de la contraseña.................................231
8.3.1. Propiedades.......................................................... 186 9.3.4. Validación del em a il.............................................. 231
8.3.2. M étodos................................................................. 188 9.3.5. Validación del idiom a............................................232
8.4. Objeto screen .....................................................................188 9.3.6. Validación del envío de publicidad..................233
9.3.7. Función principal de v alid ación ........................233
8.4.1. Propiedades............................................................ 188
9.3.8. Ejecutar la validación.............................................234
8.5. Objeto history....................................................................189
8.5.1. Propiedades.......................................................... 189 10. E v en tos.......................................................................................... 237
8.5.2. M étodos................................................................. 189
10.1. Eventos en JavaScript........................................................237
8 .6 . Objeto location ...................................................................190
10.2. Eventos en una página H TM L....................................... 238
8.6.1. Propiedades.......................................................... 190
10.3. Trabajar con ev en to s.........................................................239
8.6.2. M étodos................................................................. 191
10.3.1. Manejadores como atributos H TM L................240
8.7. Objeto docu m en t.............................................................. 192
10.3.2. Trabajar con eventos en JavaScrip t.................. 251
8.7.1. Colecciones de objetos.......................................192
10.4. El objeto ev en t..................................................................... 258
8.7.2. Propiedades.......................................................... 193
10.4.1. Propiedades............................................................. 259
8.7.3. M étodos................................................................. 194
8 .8 . Objeto an chor..................................................................... 195 11. C ookies.......................................................................................... 263
8.8.1. Propiedades............................................................ 195
11.1. Trabajar con cookies.......................................................... 265
8.8.2. M étodos...................................................................196
11.1.1. Estructura de una cook ie.....................................265
8.9. Objeto lin k ............................................................................ 196
11.1.2. Almacenar una co o k ie......................................... 267
8.9.1. Propiedades............................................................ 196
11.1.3. Recuperar una cookie........................................... 268
8.9.2. M étodos...................................................................198
11.1.4. Modificar una co o k ie ........................................... 272
8.10. Objeto im a g e .......................................................................198
11.1.5. Borrar una cookie................................................... 272
8 .10.1. Propiedades.............................................................198
11.2. Ejemplos prácticos............................................................. 273

10
11.2.1. Almacenar y recuperar una co o k ie.................. 273 C.7. R eg E xp ................................................................................... 340
11.2.2. Expiración de co o k ies...........................................275 C.7.1. Propiedades..............................................................341
11.2.3. Modificar una co o k ie ........................................... 277 C.7.2. M éto d o s.....................................................................341
11.2.4. Borrar una cookie................................................... 278
I ). Objetos del navegador (D O M )............................................... 343
12. Ejemplos p ráctico s...................................................................279
D.l. Objeto w indow .................................................................... 343
12.1. M ostrar un texto ro tativ o................................................ 279 D .l.l. Colecciones de ob jetos..........................................344
12.2. Calcular la letra del DN I.................................................. 282 D .l.2. Propiedades.............................................................. 344
12.3. Un reloj despertador.........................................................284 D.1.3. M éto d o s.................................................................... 345
12.4. Calcular los caracteres restantes de un SM S.............291 D.2. Objeto n av ig ato r................................................................. 346
12.5. La ventana que escap a..................................................... 294 D.2.1. Propiedades..............................................................347
12.6. Acceso restringido mediante una contraseña.......297 D.2.2. M éto d o s.................................................................... 347
12.7. Las tres en ra y a ...................................................................302 D.3. Objeto scre en ........................................................................347
D.3.1. Propiedades..............................................................348
13. Un paso más allá de JavaScript..............................................319
D.4. Objeto h istory .......................................................................348
13.1. D H TM L................................................................................. 319 D.4.1. Propiedades.............................................................. 348
13.2. A JA X....................................................................................... 323 ' D.4.2. M éto d o s.....................................................................348
13.3. jQ uery.....................................................................................325 D.5. Objeto lo ca tio n .....................................................................348
D.5.1. Propiedades.............................................................. 349
A. Palabras reservadas..................................................................... 329
D.5.2. M éto d o s..................................................................... 349
D.6 . Objeto d o cu m en t................................................................ 349
B. Precedencia de operadores........................................................ 331
D.6.1. Colecciones de ob jetos.......................................... 349
D.6.2. Propiedades.............................................................. 350
C. Referencia rápida a los objetos de JavaScript..................... 333
D.6.3. M étod o s..................................................................... 350
C .l. Boolean....................................................................................333 D.7. Objeto a n ch o r....................................................................... 351
C.2. N u m b er.................................................................................. 333 D.7.1. Propiedades.............................................................. 351
C.2.1. Propiedades.............................................................. 334 D.7.2. M éto d o s..................................................................... 351
C.2.2. M étod os.....................................................................334 D.8 . Objeto lin k ............................................................................. 351
C.3. S trin g .......................................................................................334 D.8.1. Propiedades.............................................................. 351
C.3.1. Propiedades.............................................................. 335 D.8.2. M éto d o s..................................................................... 352
C.3.2. M étod os.....................................................................335 D.9. Objeto im age..........................................................................352
C.4. Array........................................................................................336 D.9.1. Propiedades.............................................................. 352
C.4.1. Propiedades.............................................................. 336
E. Formularios en Jav aScrip t......................................................... 353
C.4.2. M étodos.....................................................................336
C.5. D ate..........................................................................................337 E .l. Form ulario..................................... ‘.................................... 353
C.5.1. Propiedades..............................................................338 E .l.l. Colecciones de objetos.......................................... 353
C.5.2. M étod os.....................................................................338 E .l.2. Propiedades.............................................................. 353
C.6 . M ath.........................................................................................339 E.1.3. M éto d o s..................................................................... 354
C.6.1. Propiedades..............................................................339 E.2. Campos de entrada de d a to s .......................................... 354
C.6.2. M étodos.....................................................................340 E.2.1. Propiedades...............................................................354

12 13
E.2.2. M étod o s.................................................................... 354
E.3. Campos de selección de d atos.............................................. ............ 355
E.3.1. Colecciones de objetos..........................................355
E.3.2. Propiedades..............................................................355 Introducción
E.3.3. M étod os.................................................................... 356
E.4. Botones..................................................................................356
E.4.1. Propiedades..............................................................356
E.4.2. M étodos............................................................ ......357
E.5. Resumen de tipos de cam pos..........................................357
F. Caracteres y modificadores de las expresiones
regulares........................................................................................359
F .l. Caracteres de rep etición ...................................................359
¿De qué trata este libro?
F.2. Caracteres especiales......................................................... 360
F.3. Agrupación de valores......................................................360 Esta guía práctica está dirigida a personas que, como yo
hace unos años, sienten la necesidad de hacer sus páginas Web
F.4. Caracteres de p osició n ......................................................361
más útiles o atractivas de lo que son ahora. El HTML a secas se
F.5. M odificad ores..................................................................... 361
queda pequeño cuando nos surge la necesidad de interactuar
F. 6 . Expresiones regulares útiles............................................361 con el usuario que visita nuestra página para que nos envíe
índice alfabético................................................................................ 363 una sugerencia o sencillamente para que vea lo bonito que
queda que los botones cambien de color al pasar sobre ellos.
Por esta razón, ha decidido que era el momento de ir un paso
más allá y aprender un lenguaje de programación Web como
JavaScript comprando este libro, cosa que le agradezco desde
este momento.
Mi intención no es llenarle la cabeza con tecnicismos que le
dejen una sensación de vacío y de no haber aprendido nada,
aunque hay ciertos términos que son imposibles de simplificar.
Pese a ello, en la medida de lo posible, intentaré que todas las
explicaciones sean claras y concisas, acompañándolas de un
ejemplo si eso mejora la compresión.

Navegadores Web
Todo aquel que desarrolle sitios W eb se encuentra ante
un pequeño muro cuando visualiza el sitio en los distintos
navegadores del mercado: las páginas no funcionan igual o ni
siquiera se muestran de la misma manera. Un navegador no
hace más que interpretar código HTML, ajustándose lo más
posible a unos estándares fijados, para después plasmarlo en
la pantalla del usuario de forma gráfica. Por desgracia, algunos

15
14
de ellos se desvían más que otros de esos estándares y, como Herramientas para programar
consecuencia directa, mía misma página puede tener distintas
interpretaciones, de modo que recae sobre el desarrollador el on JavaScript
hacer que sus páginas sean compatibles con todos o el mayor
número posible de navegadores, m ediante pequeños ajustes Por suerte para nosotros, JavaScript no requiere que insta-
o "trucos". Irmos y aprendamos a usar complejos entornos de desarrollo
¿Qué se debe tener en cuenta a la hora de intentar que 111tino pudiera ser Visual Studio o Eclipse) para escribir código
nuestra página sea lo más compatible posible? Dado que sería 111 nuestras páginas.
una tarea interminable el ajustarse a todos y cada uno de los Quizá se sorprenda si le digo que le será suficiente con
navegadores y sus versiones, se opta por lo más razonable: •iln*r utilizar el bloc de notas de Windows o cualquier otro
ajustar nuestro código a los navegadores más utilizados. i'ilitor de texto en su forma más básica. También puede que me
Hasta hace no mucho, existía una clara predom inancia del II.une mentiroso porque un conocido suyo le haya comentado
navegador de M icrosoft (Internet Explorer), con una cuota al­ iitu* existen editores específicos para JavaScript. Bien, déjeme
rededor del 60 por ciento, seguido por otros navegadores que i ¡Henderme;). Es cierto que hay editores avanzados (como
poco a poco han ido ganando adeptos. Esto no quiere decir l.iv.iScript Plus o Antechinus), pero la ventaja que ofrecen es
que Internet Explorer fuera el m ejor navegador, de hecho es l.ilie facilitar la tarea de escribir código sin tener que recordar
uno de los m ás criticados por ser de los que más se intentan li mlos los nombres de funciones o propiedades. Reconozco que
alejar de los estándares para im poner el suyo propio. En los i"ila ayuda es de agradecer cuando se trabaja intensivamente
dos últim os años la cosa ha cam biado bastante y el uso de i on JavaScript, pero para aprender a manejarlo (como será su
Internet Explorer ha llegado a bajar del 40 por ciento. Además i .iso si ha adquirido este libro) le recomiendo utilizar un editor
hay que sum ar la aparición de un nuevo tipo de usuario que i Ir lexto básico para familiarizarse con la sintaxis.
está en pleno auge: los que usan Sm artphones o tabletas. I’ara ver el resultado de nuestro trabajo no tendrem os
Veam os entonces una lista con el resto de navegadores que ni.is que abrir nuestra página con el navegador que tengamos
tienen una presencia importante en la W eb hoy en día: Instalado. Sin más.
• FireFox: D esarrollado por M ozilla, fue el rival m ás
directo de Internet Explorer y actualmente tiene cerca
de un 27 por ciento de cuota de m ercado. Por tanto, es Notas finales
una opción a tener en cuenta para hacer nuestras páginas
compatibles con él. Ser un "crack" de JavaScript no es algo que se consiga en
• Chrome: N avegador introducido por Google que ha •|ilince días puesto que conocer el funcionamiento de muchas
alcanzado rápidam ente una cuota del 20 por ciento, •i»* sus partes requiere cierta práctica, y más aún si contamos
convirtiéndose en un serio adversario. con todas las técnicas que se basan en él (DHTML, A JA X ...).
• Safari: Estamos ante el navegador de Apple, eterno ad­ Con este libro podrá construir una sólida base de cono-
versario de Microsoft. Aunque dispone de una versión i imientos que le permitirá enfrentarse a cualquier reto que
para W indows, su uso está más centrado en sistemas l.ivaScript pudiera proponerle.
de la propia com pañía: ordenadores M ac y sus iA-
migos (iPhone, iPad). Su cuota está alrededor del 7 por
ciento.
• Opera: Este navegador, desarrollado por Opera Software,
cuenta con una discreta cuota que supera ligeramente el
2 por ciento pese a ser un buen producto y estar presente
en varios Sm artphones en su versión Opera Mini.

16 17
Cómo usar este libro

No, no se asuste. A pesar del título de este apartado, no


Iía comprado un m anual de instrucciones sino una guía para
.1prender JavaScript. El objetivo entonces de este apartado es
adelantarle un poco con lo que se va a encontrar en cuanto
|'.ise unas páginas.
til motivo que posiblemente le habrá llevado a adquirir esta
unía es porque alguien o algo (un sitio W eb normalmente) le
h.i revelado una palabra, una tecnología, un lenguaje nuevo
ilrl que desconocía su existencia o sólo lo conocía de oídas:
JilvaScript. Esto, por supuesto, le ha llamado la atención y ha
dividido lanzarse a aprenderlo para aprovechar su potencial
V versatilidad aplicándolo a sus páginas. ¡Bien por ello! No le
defraudará en absoluto.
Aunque en esta guía se comience desde cero, cuando la ter-
mine tendrá conocimientos más que suficientes para empezar
.1 dar un toque de color a sus páginas, y ya verá como con el
I lempo querrá más y más. Y lo m ejor de todo es que JavaScript
le ofrecerá más y más posibilidades, puesto que su potencial no
acaba en la última hoja de este libro ni mucho menos, todavía
Ir quedará mucho a lo que sacarle jugo.
Sin embargo, las cosas no se hacen solas (vale, las puede
11ipiar de Internet... pero eso no es aprender JavaScript) y por
i*lio le animo a intentar aportar su granito de arena mientras
liv cada capítulo, escribiendo sus propios ejemplos (por muy
Ion tos que sean) y tratando de jugar con las opciones que
tengamos a nuestro alcance. Con esto sí podrá llegar a ad­
quirir bastante soltura en este lenguaje y ser capaz de detectar
lapidamente cuál es la línea de código que no funciona bien,
" incluso poder adaptar a otras necesidades un código que
tuviera hecho para otro propósito.

19
Conocimientos previos
Aunque aquí se van a explicar todos los conceptos y los
1
elementos utilizados en los ejemplos, podría ser ligeramente Introducción a JavaScript
favorable tener unos conocim ientos sobre H TM L pues es
la base donde opera JavaScript. De todas formas no se va a
realizar un uso intensivo de las decenas de etiquetas HTML
sino de algunas muy básicas como los encabezados, enlaces
o tablas.
Por otro lado, si ha programado antes en cualquier lenguaje,
sin duda leerá este libro con más soltura, sin detenerse en
ciertos puntos, pero si no lo ha hecho nunca tampoco debe
preocuparle puesto que lo que va a aprender a continuación es
justamente un lenguaje de programación, y todos los términos El lenguaje de programación JavaScript se utiliza en las
y elementos que se utilizan quedan detallados. páginas Web para cubrir las carencias que deja el HTM L a
secas. Incorporando este lenguaje a nuestras páginas logramos
incrementar la funcionalidad de las mismas y la interacción con
Estructura del libro el usuario, lo que se traduce en unas páginas más dinámicas.
Algunos ejemplos de su utilidad podrían ser:
Se podría decir que este libro es como una escalera, puesto • Validar los datos introducidos en un formulario.
que no podemos llegar al peldaño más alto sin pasar antes • Detectar el navegador que está utilizando el usuario.
por los demás. Por ello se ha intentado ir paso a paso con • Almacenar información del usuario para que no tenga
los capítulos, sin utilizar elementos antes de ser explicados que v olv er a ser introducida en la siguiente visita
(cosa que a veces no ha resultado fácil), para así cubrir irnos (Cookies).
conocimientos mínimos necesarios para explicar el siguiente
capítulo. Además, cada capítulo siempre tiene unos ejemplos El código que escribamos en nuestras páginas será inter­
asociados, que los considero fundamentales para comprender pretado directamente por el navegador que estemos usando,
m ejor algo con lo que nunca se ha tenido contacto antes. de modo que el servidor Web no interpreta ni ejecuta nuestro
Ahora le dejo que se sumerja en el amplio mundo de JavaS­ código. Esto lo convierte en un lenguaje del lado cliente, al
cript y espero que le resulte fácil la lectura de esta guía. ¡Nos contrario de lo que ocurre con lenguajes como PHP o ASP,
vemos en el último capítulo! donde todo se ejecuta en el lado del servidor.
Si repasam os un poco la historia desde la aparición de
Internet, nos encontramos con que se em pezaron a necesitar
una serie de funcionalidades en las páginas a principios de
Código fuente los 90 que el HTML no era capaz de satisfacer por sí solo. Un
caso m uy claro fue la validación de formularios en el servidor
Para desarrollar los ejemplos, puede optar por introducir Web, ya que la única manera posible por entonces era enviar
de forma m anual el código o utilizar los archivos de código los datos al servidor para que éste devolviera una respuesta
fuente que acompañan al libro. al usuario incluyendo los errores encontrados, si los hubiera.
En el sitio W eb de A naya M ultim edia: h t t p : //www . Otra circunstancia que agravaba este ir y venir de datos es
a n a y a m u l t i m e d i a . e s / , diríjase a la sección S o p o rte que en esa época la velocidad de conexión a Internet no era
té cn ico > C o m p le m e n to s, donde encontrará una sección de­ muy alta (del orden de decenas de kbps, frente a los mbps de
dicada a este libro introduciendo el código 2335597. hoy en día), por lo que surgió la necesidad de comprobar los

20 21
campos de los formularios en el propio navegador del usuario, • AJAX (Asynchronous JavaScript And XML): es una técnica
es decir, antes de enviar nada al servidor. Con esto se conse­ capaz de solicitar datos adicionales al servidor en un
guirían principalm ente dos cosas: segundo plano sin recargar o influir en la página que se
está mostrando en el mismo momento. Lo normal es que
1. Evitar largas esperas al usuario con la respuesta del ser­ la página se recargue por completo para poder mostrar la
vidor para subsanar un error, por pequeño que fuera. nueva información. Por ejemplo, si un usuario escribe las
2. Liberar al servidor de realizar este tipo de operaciones, primeras letras del título de una película en un cuadro de
con lo que la respuesta sería m ás rápida al tener que texto, se pueden solicitar las coincidencias con un listado
realizar m enos trabajo. completo y mostrárselas al usuario para que elija.
Brendan Eich, durante su trabajo en la em presa Netscape En el capítulo 13 puede encontrar una descripción un poco
Communications, desarrolló un lenguaje capaz de dar solu­ más amplia sobre estas técnicas, a modo informativo ya que
ción a este problema, apareciendo por prim era vez en el nave­ no son el objetivo de esta guía. Le recomiendo que, una vez
gador Netscape 2.0 con un gran éxito. Inicialm ente lo llamaron haya adquirido los conocimientos sobre JavaScript mediante
M ocha, más tarde LiveScript y finalm ente fue rebautizado los capítulos siguientes, consulte otros libros de esta editorial,
como JavaScript cuando Netscape se alió con Sun Microsystems como "CSS, DHTM L y AJAX", el cual tuve ocasión de leer y
(creadores del lenguaje Java). me sirvió de gran ayuda para ampliar mis conocim ientos y
añadir funcionalidades a mis páginas que antes me parecían
Nota: Es importante no confundir Java con JavaScript ya muy complejas.
que, si bien su nombre y sintaxis son similares, su propósito
y complejidad son muy distintas.
1.1. Versiones de JavaScript
Después del lanzamiento de la primera versión de JavaScript,
M icrosoft (autores del navegador rival de Netscape, Internet y los navegadores
Explorer) desarrolló su propio lenguaje del lado del cliente,
al que denominaron JScript, que no era m ás que una copia de Con el paso del tiempo se han ido implementando nuevas
JavaScript adaptada a su propio navegador. M ás adelante de­ y ampliadas versiones de JavaScript para soportar nuevas
sarrollarían también VBScript, basado en Visual Basic. funcionalidades, lo cual obliga a actualizar los navegadores,
dado que es donde se interpreta el código, y así poder mostrar
Nota: JavaScript es soportado por cualquier navegador grá­ correctamente una página que utilice estas nuevas versiones.
fico actual, mientras que JScript y VBScript sólo pueden ser Por todo esto, el prim er problem a al que se enfrentaba
utilizados junto con Internet Explorer. un program ador de código JavaScript es que los usuarios
no siempre tenían la últim a versión de los navegadores y,
El uso de JavaScript se ha ido extendiendo y evolucionando por tanto, algunas instrucciones podrían no ser reconocidas.
a medida que la complejidad de las páginas lo requería. De Actualmente es raro encontrar un navegador que no soporte al
este modo podemos encontrarnos con técnicas de desarrollo menos la versión 1.5 de JavaScript (véase la tabla 1.1) aunque
como: seguimos teniendo otros problemas a la hora de escribir nuestro
código por la existencia de distintos DOM (Document Object
• DHTM L (Dynamic HTML): m ediante el uso de HTML, Model). Al cargar una página, los navegadores crean una jerar­
CSS y JavaScript esta técnica es capaz de crear efectos quía de objetos, cada uno de los cuales representa un elemento
visuales y aumentar la interactividad con el usuario. de la misma. Esta jerarquía es la que permite a los desarrolla-
Por ejemplo, podemos crear un m enú desplegable de dores acceder y manipular todos los elementos que contiene
forma que al pasar el puntero del ratón por encima de dicha página (por ejemplo, guardar el teléfono introducido
cada opción del menú aparezcan a su lado las opciones en un formulario). Aunque existe un estándar definido para
que tiene asociadas.

22 23
crear el DOM, en algunos navegadores o incluso en distintas
versiones del mismo navegador, los objetos no siem pre se versiones. Por tanto, no es recomendable utilizar características
com portan igual. de la última versión si queremos que nuestro código pueda ser
Siempre que programemos un código JavaScript es con­ ejecutado por el mayor número posible de navegadores.
veniente probarlo en distintos navegadores para asegurar su En su versión 1.3, Netscape Com munications presentó su
correcto funcionamiento. En otro caso, estaremos dejando que lenguaje a ECMA (European Computer Manufacturers Association),
un grupo de visitantes de nuestra página no pueda visualizarla organización que se encarga de crear estándares con el fin
correctamente o incluso que no pueda interactuar con ella. de facilitar el uso de las Tecnologías de Información. Como
resultado de esta estandarización, surgió la especificación
ECMAScript, a la cual se ajustó JavaScript en las versiones
Tabla 1.1. Versiones de JavaScript y navegadores que las
soportan. posteriores.

Versión JavaScript Navegador 1 Tabla 1.2. Versiones ECMAScript adaptadas en JavaScript.

1.0 Netscape (2.0) Versión ECMAScript Versión JavaScript


1.1 Netscape (3.0)
ECMA-262 (2a edición) 1.3
1.2 Netscape (4.0-4.05)
ECMA-262 (3a edición) 1.5
1.3 Netscape (4.06-4.7x), Internet
ECMA-262 (5a edición) 1.8.5
Explorer (4.0)
1.4 Netscape Server
1.5 Netscape (6.0), Internet Explorer 1.2. Integración con HTML
(5.5-8.0), FireFox (1.0), Opera
(6.0-9.0), Chrome (1.0), Safari
Para poder insertar nuestro código JavaScript dentro de
(3.0.5)
una página HTML, disponemos de la etiqueta <SCRIPT>.
1.6 FireFox (1.5) Su contenido será interpretado y/o ejecutado según se vaya
1.7 FireFox (2.0), Safari (3.x) cargando la página.
FireFox (3.0), Opera (11.5) Esta etiqueta debe usarse junto con el atributo TYPE, el
1.8
cual es obligatorio. A nteriorm ente se utilizaba el atributo
1.8.1 FireFox (3.5)
LANGUAGE, pero hace tiempo que está en desuso. Para el caso
1.8.2 FireFox (3.6) de JavaScript, debemos etiquetar nuestro código de la siguiente
1.8.5 FireFox (4.0), Internet Explorer manera:
(9.0)
<SCRIPT TYPE="text/javascript">
Nuestro código
Nota: La tabla 1.1 refleja los navegadores que tienen un </SCRIPT>
soporte total o muy cercano sobre la versión de JavaScript Si el código utiliza alguna característica especial de una
correspondiente. Aún así, existen versiones más recientes versión en concreto, podremos especificarla de la siguiente
de navegadores que soportan parte de las funcionalidades de manera: TYPE="text/javascript; version=l.6". En
versiones superiores de JavaScript. caso de que el navegador no la soporte, ignorará el código que
contenga esa etiqueta.
Cada versión de JavaScript es compatible hacia atrás con Cuando tenemos un código muy extenso y queremos reuti-
las antiguas, es decir, un código escrito para una versión con­ lizarlo en otras páginas, podríamos pensar que tendríamos que
creta siempre será ejecutado correctamente en las siguientes escribirlo repetidas veces haciendo que su mantenim iento sea
difícil pero, afortunadamente para nosotros, existe la posibi­
24
25
lidad de meterlo en un fichero con extensión ".js" y utilizar
1.3.1. Mayúsculas y minúsculas
además el atributo SRC de la etiqueta <SCRIPT> para incluirlo JavaScript es capaz de distinguir mayúsculas y minúsculas
en todas las páginas que lo necesiten, suponiendo un esfuerzo en los nombres de variables, funciones u otros objetos. Por
bastante menor: tanto, no será lo mismo la variable posicion que la variable
<SCRIPT TYPE="text/javascript" SRC="mi_codigo.js"> Posicion o incluso que una tercera llamada POSICION, pu­
</SCRIPT> diendo estar definidas todas a la vez y con valores totalmente
En este caso, si escribim os código adicional dentro de la distintos.
etiqueta <SCRI PT>, éste será ignorado por el navegador dado Debemos tener cierto cuidado mientras escribimos nuestro
código, ya que estos pequeños matices pueden dar algún que­
que estam os usando el atributo SRC.
bradero de cabeza, sobre todo las primeras veces que progra­
<SCRIPT TYPE=”text/javascript" SRC="mi_codigo.js"> memos en JavaScript.
Lo que pongamos aquí no se ejecutará Por norma general se usarán las m inúsculas para evitar
</SCRIPT>
este tipo de conflictos, aunque ya veremos que se usan algunas
H ay dos sitios dentro de una página donde podemos situar reglas (recomendadas pero no obligatorias) para mejorar la
nuestro código, el número de veces que queramos: lectura y comprensión del código.
1. Dentro de la etiqueta <HEAD>. Esta posición se suele
utilizar normalmente para cargar ficheros externos que 1.3.2. Comentarios
vamos a utilizar en otras partes de la misma página.
2. Dentro de la etiqueta <BODY>. Aquí se coloca habi­ Los comentarios en el código sirven para ayudar al progra­
tualmente el código que va a realizar acciones sobre la mador u otra persona a comprender m ejor su funcionamiento,
página, pudiendo hacer referencia a parte del código o simplemente para dejar anotaciones que nos puedan ser de
cargado dentro de <HEAD>. interés (autor del código, fecha en la que se escribió, etc.).
Todo texto que se escriba como comentario no será interpre­
<HEAD>
tado por el navegador, por lo que su contenido es irrelevante
<SCRIPT TYPE="text/javascript" SRC=”mi_codigo.js">
</SCRIPT>
para él. Existen dos tipos de comentarios:
</HEAD> 1. Línea simple: se identifican escribiendo dos barras (/ /)
<BODY>
al comienzo de la línea, y van seguidas del texto que
<SCRIPT TYPE="text/javascript">
Aqui hago algunas operaciones queramos etiquetar como comentario.
</SCRIPT> 2. Multilínea: si el comentario es muy extenso o queremos
</BODY> presentarlo en varias líneas, entonces debemos escribir
una barra junto a un asterisco (/ *) al principio del texto
Ya iremos viendo que existen algunas restricciones cuando
y un asterisco junto a una barra (* /) al final del mismo.
ponemos nuestro código en el <BODY>.
<SCRIPT TYPE="text/javascript">
// Esto es un comentario corto de una línea.
/* En cambio este otro ocupa más espacio y,
1.3. Sintaxis del lenguaje además,no pasa nada si escribo algo de
código como alto = 5; ya que estamos en
La sintaxis de JavaScript es muy parecida a la de otros len­ un comentario. */
guajes como Java y C, por lo que si ya conoce esos lenguajes ancho = 7 ; // Sí se ejecuta el código, pero
este texto no.
se sentirá cómodo escribiendo código. De cualquier modo,
/* Esto es sólo una línea, pero también
lo explicarem os a continuación para que ningún lector tenga es válido. */
problem as a la hora de adentrarse en el m undo JavaScript. </SCRIPT>

27
26
1.3.3. Separación de instrucciones 1.4. Navegadores sin soporte JavaScript
Para separar las distintas instrucciones que contiene nuestro Aunque no es algo común, puede darse la posibilidad de
código tenemos dos opciones: que el visitante de nuestra página esté usando un navegador
que no soporte JavaScript, o simplemente lo tenga desactivado.
1. Escribir un punto y coma ( ; ) al final de cada una de las
En estos casos, todo el código que tengamos escrito no será
instrucciones.
interpretado ni ejecutado, por lo que el visitante no será capaz
2. Insertar un salto de línea al terminar cada una de las
de ver correctamente nuestra página o hacer uso de ella.
instrucciones.
La causa de esto es que el navegador no reconoce la etiqueta
De este m odo, los siguientes ejemplos funcionarán correc­ <SCRIPT>, por lo que todo el código que hayamos escrito
tamente en JavaScript: dentro de ella puede ser ignorado o llegar a ser mostrado como
un texto HTML. Para evitar esto último, es bueno marcar el
// Código utilizando punto y coma
<SCRIPT TYPE="text/j avascript”>
código como un com entario HTML, usando < ! — al principio
numero = 1; y — > al final, con la particularidad de escribir el cierre de co­
cuadrado = numero * numero; mentario a su vez como un comentario JavaScript para evitar
</SCRIPT> que el navegador lo interprete como parte de nuestro código.
// Código utilizando salto de linea Lo explico a continuación:
<SCRIPT TYPE="text/javascript">
numero = 1 <SCRIPT TYPE="text/javascript">
cuadrado = numero * numero < !--
</SCRIPT> numero = 4 ;
cuadrado = numero * numero;
N o siem pre es necesario que cada instrucción comience // —>
en una línea nueva, pero si ponemos varias instrucciones se­ </SCRIPT>
guidas en la misma línea entonces estamos obligados a utilizar Adicionalmente, tenemos un 'a s en la m anga' para advertir
el punto y coma para separarlas, ya que de otro modo se in­ al usuario de que su navegador no soporta JavaScript: la eti­
terpreta todo como una tínica instrucción, con el consecuente queta <NOSCRIPT>. El contenido HTML de esta etiqueta sólo
error de sintaxis. será mostrado si el navegador no puede interpretar JavaScript.
// Varias instrucciones utilizando punto y coma -> Veamos un ejemplo:
Funciona <HTML>
<SCRIPT TYPE="text/j avascript"> <BODY>
alto = 5; ancho = 7; area - alto * ancho;
<SCRIPT TYPE="text/javascript">
</SCRIPT> <! —
// Varias instrucciones sin punto y coma ->
numero = 4;
Genera un error cuadrado = numero * numero;
<SCRIPT TYPE="text/javascript">
// — >
alto = 5 ancho = 7 area = alto * ancho </SCRIPT>
</SCRIPT>
¡Bienvenido a mi página!
<NOSCRIPT>Lo siento, pero tu navegador no soporta
N ota: Es aconsejable acostum brarse a escribir cada ins­ JavaScript :(</NOSCRIPT>
trucción en una nueva línea y utilizar un punto y coma al </BODY>
fin al para que la apariencia de nuestro código sea clara y se </HTML>
asemeje a la habitual en otros lenguajes, como java o C. A sí Un navegador que soporte JavaScript ejecutará nuestro
mismo, un correcto tabulado del código ayudará a mejorar código y mostrará únicamente el mensaje de bienvenida, m ien­
su compresión. tras que los navegadores que no lo hagan ignorarán el código

28 29
y mostrarán tanto el mensaje de bienvenida como el aviso. En
lugar de m ostrar sólo este aviso, también podemos dar la op­
ción al usuario de dirigirse a una página que hayamos creado
con aspecto similar, pero sin usar JavaScript.
2
<NOSCRIPT> Variables, tipos de datos
Lo siento, pero tu navegador no soporta JavaScript
: (<BR> y expresiones regulares
Sin embargo, puedes ver una página similar
<A HREF="pagina_sin_javascript.html">aquí</ñ>
</NOSCRIPT>

A d v erten cia: Si el navegador no soporta la versión de


JavaScript que hayamos especificado (por ejemplo la 1.6),
tampoco se mostrará el texto contenido en <NOSCRIPT> ya
que sí es capaz de reconocer la etiqueta <SCRIPT>.
2.1. Variables
Una variable es un espacio de memoria donde almacenamos
tem poralm ente un dato que utilizam os en las operaciones
dentro de nuestro código como, por ejemplo, el resultado de
una suma. Ese dato podrá ser recuperado en cualquier m o­
mento e incluso ser modificado.
En el código, cada variable estará identificada por un
nombre a nuestra elección y que podrá estar formado por ca­
racteres alfanuméricos, el carácter guión bajo o subrayado ( )
y el símbolo de dólar ($). La única restricción es que no puede
comenzar por un número. También es im portante destacar
que se distingue entre mayúsculas y minúsculas, por lo que la
variable suma no será la misma que la variable SUMA.

Tabla 2.1. Ejemplos de nombres de variables.

Nombre válido Nombre no válido

dos_numeros 2_numeros
nombrel nombre-1
Documento %Documento
nombreApellidos nombre&apellidos
$dinero €dinero

También debe tener en cuenta que el nombre de una va­


riable no puede coincidir con el de una palabra reservada de
JavaScript (ver apéndice A), ni con el de otro elemento que
hayamos definido (funciones u objetos).
30
Aunque no hay obligación para ello, es una buena prác­ Opcionalmente, podemos asignar un valor a la variable al
tica usar minúsculas en los nombres de variables excepto si mismo tiempo que se declara, lo cual se conoce como iniciali-
se compone de varias palabras, en cuyo caso escribiremos en zación, a través del operador de asignación = (explicado más
mayúsculas la primera letra de cada palabra siguiente a la pri­ adelante). Esta inicialización es ineludible si hacemos declara­
mera. Por ejemplo: nombre, miNombre,miNombreCompleto. ciones implícitas, como hemos visto hace un momento.
Con el uso de esta sencilla regla estaremos haciendo nuestro <SCRIPT TYPE="text/javascript">
código más limpio y fácil de seguir por otro program ador o // Declaración explícita con inicialización
nosotros mismos a la hora de retomarlo. var alto = 5 ;
// Declaración implícita con inicialización
ancho = 12;
2.1.1. Declaración de variables // Declaración explícita múltiple con inicialización
var alto = 5, ancho = 12, profundo = 7;
Para utilizar una variable en nuestro código debe estar // Declaración implícita múltiple con inicialización
indicado en alguna parte de éste cuál es su nombre y, si pro­ hora = 14, minutos = 35, segundos = 41;
// Declaración explícita múltiple con y sin
cede, el valor que le queremos dar. A esto se le conoce como, // inicialización
declaración de una variable. var calle, numero = 7, piso = 3;
En la mayoría de lenguajes de programación es obligatorio </SCRIPT>
declarar cada variable antes de utilizarla en el código pero en
JavaScript se puede hacer sobre la marcha según las vayamos Si declaramos la misma variable más de una vez y la ini-
necesitando. No obstante, como queremos hacer un código ejem­ cializamos con valores, prevalecerá el último que hayamos
plar, es bueno que nos acostumbremos a declarar las variables asignado.
antes de darles uso. Para ello existen dos maneras de hacerlo: <SCRIPT TYPE="text/javascript">
// Declaración de la misma variable dos veces (alto
1. Declaración explícita: Consiste en usar la sentencia va r // valdrá 8)
seguida del nombre de la variable. Esta opción es la var alto = 5;
recom endada para añadir claridad al código. var alto = 8;
2. Declaración implícita: Es cuando escribim os directa­ </SCRIPT>
mente el nombre de la variable sin una sentencia previa.
Recordemos la importancia de las mayúsculas y minúsculas
En este caso debe ir acompañada obligatoriamente de un
puesto que estaremos definiendo variables distintas.
valor si no queremos obtener un error de declaración.
<SCRIPT TYPE="text/javascript">
<SCRIPT TYPE="text/j avascript">
// Declaración con mayúsculas y minúsculas
// Declaración explícita var alto = 5;
var miEdad; var Alto = 8;
// Declaración implícita (errónea al no tener </SCRIPT>
// un valor)
miEdad;
// Declaración implícita (correcta) 2.1.2. ¿Y las constantes?
miEdad = 26;
</SCRIPT>
Una constante es un dato cuyo valor no puede ser m odifi­
También es posible declarar explícitamente varias variables cado después de haber sido inicializado. Esto es útil cuando
a la vez, separando sus nombres por comas: necesitamos trabajar con valores fijos como, por ejemplo, el
número Pi (3,14).
<SCRIPT TYPE="text/javascript">
Aunque es posible declarar constantes en JavaScript a través
// Declaración explícita múltiple
var nombre, apellidos, edad; de la sentencia const, ésta sólo es soportada desde la versión
</SCRIPT> 1.5 de JavaScript y principalmente por los navegadores basados

32 33
en Mozilla (como FireFox), aunque se prevé que tenga total in­ variable puede cambiar su tipo de datos a lo largo de un script
tegración con la versión 2.0 de JavaScript. Los navegadores que sin que esto provoque errores, aunque es poco común hacer
no la soporten ignorarán todas las declaraciones que hagamos este tipo de acciones.
utilizando const haciendo que aparezcan errores cuando se
<SCRIPT TYPE="text/javascript">
intente utilizar una de esas constantes en nuestro script. // Declaración de variable
<SCRIPT TYPE="text/javascript"> var edad;
// Declaración de constantes I I La variable es un número...
const pi = 3.14; edad = 30;
const valorMaximo = 256; I I y ahora un texto
</SCRIPT> edad = "treinta";
</SCRIPT>
Si está acostumbrado a program ar en otros lenguajes es
posible que lo siguiente le resulte extraño pero, para asegurar Nota; En algunos de los ejemplos que veremos a lo largo del
el funcionamiento de nuestro código en los distintos navega­ libro se utiliza la instrucción a l e r t , cuyo funcionam iento
dores, definiremos nuestras constantes como una variable (¡a aún no hemos explicado, pero de momento le adelanto que
grandes males, grandes remedios!). nos permite mostrar el valor de una variable en la pantalla.
Para poder diferenciarlas claram ente de las variables nor­ De esta form a podrá escribir los ejemplos en su ordenador y
males, podemos escribir su nombre completamente en mayús­ comprobar los resultados: a l e r t ( e d a d ) ;
culas y separaremos las palabras que la form en con guiones
bajos o subrayados (_). A continuación veremos todos los tipos de datos que m a­
<SCRIPT TYPE="text/javascript"> neja JavaScript.
// Declaración de constantes como variables
var PI = 3.14;
var VALOR_MAXIMO = 256; 2.2.1. Números
</SCRIPT>
Como viene siendo habitual, JavaScript se diferencia de
Advertencia: Las constantes definidas con ¡a sentencia v a r nuevo de otros lenguajes de program ación ya que sólo tiene
7 10dejan de ser variables, por lo que su valor sigue siendo un tipo de valor numérico. Por tanto, todo núm ero que es­
modificable a través del código. Tenga cuidado de no alterar cribamos, ya sea entero o real, será considerado del mismo
el valor de una constante. tipo. También lo serán los núm eros reales escritos en notación
científica mediante el indicador de exponente E o e. Veamos
algunos ejemplos:

2.2. Tipos de datos <SCRIPT TYPE="text/javascript">


// Declaración de datos de tipo numérico
var altura = 5;
En nuestro código vamos a utilizar inform ación de distinta var precio = 12.65;
clase, como textos o números. Estas clases son las que se co­ var temperatura = -3.0;
nocen como tipos de valores o tipos de datos, de forma que var PI = 3.141592;
cada variable o constante que definamos pertenecerá a uno var seiscientos = 6E2;
var sieteMilimetros = 7e-3;
de ellos. var MILLON_Y_MEDIO = 1.5e6;
Una de las muchas particularidades de JavaScript, en su ■;/SCRIPT>
afán por hacer más cóm oda la program ación con este len­
guaje, consiste en no tener que definir el tipo de una variable
al declararla, será el propio JavaScript el que determine a cuál Nota: El separador decimal para los números reales es el punto
corresponde en función del valor asignado. Gracias a esto, una ( . ) y ñ o la coma ( ,) .

34 35
Además, los números enteros pueden ser representados en
otros sistemas distintos al decimal (base 10 ): Advertencia: Tenga de nuevo en cuenta la importancia del
uso de mayúsculas y minúsculas, ya que JavaScript no reco­
• Sistem a octal (base 8 ): Utiliza dígitos del 0 al 7 para nocerá valores del estilo True o TRUE como un booleano.
representar un número. Para ello debemos escribir un
cero (0) delante del número. Este sistema está obsoleto,
aunque JavaScript 1.5 mantiene un soporte para él con 2.2.3. Cadenas
tal de mantener la com patibilidad hacia atrás.
Otra clase de inform ación muy común en los scripts es la
• Sistema hexadecim al (base 16): Consta de 16 dígitos:
cadena de caracteres o string. Este tipo consta de un texto con
los comprendidos entre el 0 y el 9 y las letras entre la
cualquier carácter (letras, números y símbolos).
A y la F (minúsculas o mayúsculas). Para representarlo
Las cadenas o strings se escriben en el código entre co­
tenemos que escribir un cero y una equis (Ox) antes que
m illas dobles (" ) o sim ples ( ' ) pero nunca com binadas. Lo
el número.
más habitual es utilizar las com illas dobles para representar
un texto.
Tabla 2.2. Ejemplos de números en distintas bases.
<SCRIPT TYPE="text/j avascript">
Base Número Equivalencia en base 10 // Declaración de datos de tipo cadena o string
var idioma = "español";
10 23 23 var dni = '12345678A';
var dirección = "C/ Mayor, 5";
8 027 23
var FICHERO = "mi_codigo.js";
16 0x17 23 // Declaración errónea de datos de tipo cadena o string
10 127 127 var pais = "España';
</SCRIPT>
8 0177 127
16 0x7 F 127 Caracteres especiales
16 0x7f 127 A veces es necesario incluir en el texto de una variable
ciertos caracteres, como una comilla simple ( ') , el fabulador
o el salto de línea, que deben escribirse de una forma concreta
2.2.2. Lógicos para que JavaScript pueda reconocerlos.
Para identificar esos caracteres especiales utilizaremos lo
Este tipo, conocido también como boolean o booleano, tan que se denomina carácter de escape, que no es más que una
sólo abarca dos valores posibles: verdadero (true) y falso
barra inversa o backslash (\). Este carácter de escape irá colocado
(false), que nos servirán principalm ente para tomar deci­ delante del carácter que se quiera incluir expresado mediante
siones sobre realizar una serie de acciones o no en nuestro un código (véase la tabla 2 .3 ).
código. Un ejemplo con una situación cotidiana sería: Si llueve
entonces me llevo el paraguas, en otro caso lo dejo en casa.
Nuestra variable booleana sería llueve, y, en función de su Tabla 2.3. Lista de caracteres especiales.
valor (true o false), realizaría una acción u otra (llevarme Código Modo Descripción
el paraguas o dejarlo en casa). del carácter de empleo
<SCRIPT TYPE="text/javascript"> ti
V Comilla doble
I I Declaración de datos de tipo lógico o booleano
var esVerdadero = true; ‘ V Comilla simple
var esFalso = false; \ w Barra inversa o backslash
var COMPROBAR = true;
</SCRIPT> n \n Nueva línea

36
37
[Aplicación JavaScript]
Código Modo Descripción
•jj . E ste libro s e titula "Guía d e JavaScript"
del carácter de empleo

Tabulador [ Aceptar ]
t \t
r \r Retorno de carro
Figura 2.2. Ejemplo 2 de caracteres especiales en cadenas.
b \b Retroceso o backspace
f \f Avance de página <SCRIPT TYPE="text/javascript">
V \v Tabulador vertical // Ejemplo 3 de caracteres especiales en cadenas
var cadena = "Primera linea\nSegunda linea\nTer\
u00A9era linea",-
Existe también la posibilidad de incluir cualquier carácter // Mostramos su valor
UNICODE (http://www.Unicode.org) m ediante la sen­ alert(cadena);
tencia de escape \ u xxxx, donde x x x x representan los dígitos </SCRIPT>
hexadecim ales de un carácter. Por ejemplo, los dígitos 00A9
corresponden al símbolo de copyright (©), el 0 0 0 9 al tabulador [Aplicación JavaScript] IScl
y el 0 0 2 2 a la comilla doble. La realidad es que rara vez se usan, /¿\ Primera Inea
\ Segunda linea
siendo los más com unes los contenidos en la tabla 2.3. T er© era linea

Si utilizamos el carácter de escape con otro carácter fuera [T Aceptar f


de los mencionados el resultado será dicho carácter, es decir,
se representa a sí mismo. De esta forma, si escribiésemos \c Figura 2.3. Ejemplo 3 de caracteres especiales en cadenas.
en la cadena, aparecería el carácter "c".
Veam os algunos sencillos ejemplos junto con el resultado
visto por pantalla:
2.2.4. Objetos
<SCRIPT TYPE="text/javascript"> Aunque este libro contiene un capítulo dedicado en exclu­
// Ejemplo 1 de caracteres especiales en cadenas siva al manejo de objetos en JavaScript, aquí explicaré lo que
var cadena = "El fichero está en C: \\Documentos , es un objeto, puesto que se trata de un tipo más.
// Mostramos su valor A grandes rasgos, un objeto es una estructura que engloba
alert(cadena);
una serie de datos (propiedades) y las funcionalidades nece­
</SCRIPT>
sarias para manejarlo (métodos).
Para que tenga una pequeña idea de cómo imaginarse un
[Aplicación JavaScript] Bl objeto, veámoslo con un ejemplo: pensemos en un coche (¡ese
El fichero e stá en C:\Documentos
con el que tanto sueña!), el cual tiene un conjunto de caracte­
rísticas como el color, el modelo y la marca y una serie de fun­
| Aceptar |
cionalidades como arrancar, acelerar y frenar. En este contexto,
el objeto sería el coche, las propiedades sus características y
Figura 2.1. Ejemplo 1 de caracteres especiales en cadenas.
los m étodos sus funcionalidades asociadas.
Ahora bien, como no todos los coches son iguales necesitamos
<SCRIPT TYPE="text/javascript">
poder especificar las características individuales de cada uno. A
// Ejemplo 2 de caracteres especiales en cadenas
var cadena = "Este libro se titula V'Guia de
cada uno de ellos se le denomina instancia. Para el caso que nos
JavaScriptV' ocupa, podríamos definir una instancia del objeto "coche" asig­
// Mostramos su valor nando valores concretos a sus propiedades: color "Rojo", modelo
alert(cadena); "Punto" y marca "Fiat". Los métodos que tendrá esta instancia
</SCRIPT> serán los mismos que los del objeto: arrancar, acelerar y frenar.

39
38
Objeto coche com o resultado de la operación que hem os tratado
de hacer. Tam bién existe el valor infinito negativo
r
Color
(-Infinity) cuando la operación se realiza con nú­
Propiedades <Modelo
m eros negativos.
l Marca
r Arrancar Tabla 2.4. Ejemplos con valores especiales.
Métodos < Acelerar
l Frenar Operación Valor
Figura 2.4. Representación del objeto "coche". var numero; undefined
var ahorros = nuil; nuil
Instancia miCoche var división = 0/0; NaN
r Color: Rojo var fracción = 5/0; Infinity
Propiedades -i Modelo: Punto
var fracción = -1/0; -Infinity
l Marca: Fiat
var suma = numero + 5; NaN (numero no estaba inicializado)
r Arrancar
Métodos < Acelerar
l Frenar
Figura 2.5. Representación de una instancia del objeto "coche".
2.3. Expresiones regulares
Una expresión regular, o patrón, nos permitirá buscar co­
Para que le vaya resultando fam iliar, le confesaré que
incidencias dentro de un texto (por ejemplo, todas las palabras
cuando asignam os un valor de cualquier tipo (núm eros,
que tengan la letra T) o comprobar que una cadena tiene un
booleanos y cadenas) a una variable, ésta se convierte en
formato concreto (el DNI de una persona).
realidad en una instancia de un objeto con sus propiedades
y métodos propios. No se preocupe si esto le choca un poco Esto nos será especialmente útil cuando queramos realizar
de golpe una misma operación sobre un grupo determinado
ahora, puesto que lo explicaré en capítulos posteriores con más
de palabras como, por ejemplo, cambiar a mayúsculas todas
detalle y verem os algunos ejemplos que, espero, no le dejen
con los ojos abiertos de sorpresa. las palabras que contengan la cadena "JavaScript". Con los
métodos tradicionales tendríamos que buscar en el texto pa­
labra por palabra hasta encontrar la que nos interesa y después
2.2.5. Valores especiales cambiarla a mayúsculas.
En un cap ítu lo p o sterio r v erem os cóm o trabajar con
Las variables en JavaScript pueden tomar una serie de va­ estos patrones dentro de nuestro código a través del objeto
lores especiales cuando estamos trabajando con ellas: RegExp.
• Indefinido (undefined): Este valor indica que la va­
riable aún no ha tomado ningún valor. 2.3.1. Escribir una expresión regular
• Nulo (nuil): Nos permite definir o comprobar que una
variable está vacía. En JavaScript las expresiones regulares se identifican colo­
• No numérico (NaN, Not a Number): Una variable recibe cando unas barras (/) al principio y al final de la cadena que
este valor si almacena el resultado de alguna operación la constituyen.
matemática no válida (división por cero, por ejemplo). Tenemos dos opciones a la hora de definir una expresión
• Infinito (Infinity): N os indica que una variable regular para encontrar las palabras que nos interesan: usar un
num érica ha tomado un valor dem asiado alto (infinito) patrón simple o uno con caracteres especiales.

40 41
Tabla 2.5. Ejemplos de patrones con caracteres de repetición.
Patrón sim ple
Patrón Significado Valores
Consiste en escribir un conjunto de caracteres para después que lo cumplirían
encontrar coincidencias directas con él, es decir, nuestro con­
junto de caracteres deberá aparecer dentro de la palabra en el /hola*/ "hol" seguido de hol, hola, holaaaaa
mismo orden en que están escritos. cero o más aes.
Supongamos que tenemos el texto "el pájaro saltó del nido" /hola+/ "hol" seguido de hola, holaaaaa
y el patrón / e l/ . Si aplicásemos el patrón, obtendríamos que una o más aes.
las palabras "el" y "del" lo cum plen mientras que el resto no
/hola?/ "hol" seguido de hol, hola
entrarían en el saco.
cero o una "a".
Patrón con caracteres especiales /hola{2} /"hol" seguido de holaa
exactamente dos aes.
Para hacer más útiles las expresiones regulares, podemos
/hola{2,}/ "hol" seguido de holaa, holaaaaa
utilizar una serie de estructuras y caracteres especiales que
dos o más aes.
nos permitirán crear patrones más complejos y adaptables a
nuestras necesidades. Para que le sea más fácil comprender el /hola{2,4}/ "hol" seguido de holaa, holaaa, holaaaa
funcionamiento de cada uno, los vam os a agrupar en base a dos a cuatro aes.
su funcionalidad. /ho+la*/ "h" seguido de una o hol, hooool, hola, hoolaaa
más oes, seguido de "1"
Caracteres de repetición
y seguido de cero o
Gracias a estos caracteres podrem os indicarle a nuestro más aes.
patrón que se busquen coincidencias teniendo en cuenta que
algunas partes de la cadena pueden repetirse un número de­
A dvertencia: H ay que remarcar que en los ejemplos de la
terminado de veces. Pasemos a ver las distintas opciones que
tabla 2.5 las palabras que contengan más letras a continua­
tenemos para ello: ción del patrón encontrado serán igualm ente válidas, es
• Asterisco (*): Nos permite indicar que el carácter que le decir, en estos ejemplos no se obliga a que la palabra termine
precede puede aparecer cero o más veces. estrictam ente con el último carácter del patrón, sino que
• Más (+): En este caso indica que el carácter que le precede puede haber más letras después. Pongamos como ejem plo
puede repetirse tina o más veces. el patrón / h o l a + / . Si nuestra palabra fu ese "holaaas!"
• Interrogación (?): Igual que los anteriores, pero indi­ nuestro patrón encontraría coincidencia con ella puesto que
cando que el carácter puede aparecer ninguna o una lo contiene ("holaaa") y de este modo la parte restante no
vez. afectaría ("si").
• {n}: Siendo n un entero positivo, esta estructura nos
permite indicar que el carácter que le precede se debe Caracteres especiales
repetir exactam ente el número de veces especificado Funciona de forma exacta a lo visto en el apartado anterior,
por n. donde explicamos los caracteres especiales de las cadenas. En el
• {n,}: Similar al anterior, pero esta vez se especifica que caso de las expresiones regulares, los caracteres que se utilizan
el carácter debe aparecer al m enos n veces. tienen bastantes coincidencias con los de las cadenas aunque
• {n, m}: Esto supone una ampliación de los anteriores con hay otros más complejos:
la que, teniendo n y mcomo enteros positivos, podemos
indicar que el carácter que preceda a esta estructura • Punto ( .) : Si lo escribimos dentro de un patrón, coin­
debe repetirse un núm ero de veces entre las definidas cidirá con cualquier carácter simple excepto con el de
por n y m. salto de línea.

43
42
• \n: Coincide con el carácter de nueva línea (o salto de Patrón Significado Valores que lo cumplirían
línea).
• \r: El retom o de carro. /java\tscript/ "java" seguido de java script
• \ t: Carácter de tabulado. un tabulado y
• \v: El de tabulado vertical. de "script".
• \ f : Avance de página. /java\bscript/ "java" seguido de java[NUEVA LÍNEA]
• \ u xxxx: Coincide con el carácter UNICODE que tiene un separador y script, java script
como código cuatro dígitos hexadecim ales represen­ de "script".
tados por x x x x .
/java\Bscript/ "java" no seguido de java-script, javaOscript,
• \b: Coincide con un separador de palabra, como puede
un separador y java*script
ser el espacio o el carácter de nueva línea.
de "script".
• \B: Coincide con un carácter que no sea separador de
palabra. /java\dscript/ "java” seguido de javaOscript, java6script
• \cX: Coincide con un carácter de control en una cadena un dígito y
siendo X dicho carácter, es decir, equivale a la com bina­ de "script".
ción de teclas Control-X. /java\sscript/ "java" seguido de java[NUEVA LÍNEA]
• \d: Coincide con un dígito entre cero y nueve. un carácter de script, java script, java
• \D: Coincide con un carácter que no sea un dígito. separación y script
• \s: Coincide con un único carácter de separación (es­ de "script".
pacio, tabulado, avance de página o nueva línea). /java\wscript/ "java" seguido de java5script, javaX
• \S: Coincide con un único carácter que no sea de sepa­ un carácter alfanu­ script, javaxscript,
ración. mérico o subrayado java_script
• \w: Coincide con cualquier carácter alfanumérico (letras y de "script".
de la "a" a la "z", m inúsculas o mayúsculas y números /javascript\0/ "javascript" seguido JavaScript[NULO]
del cero al nueve) o el subrayado. de un carácter nulo.
• \W: Coincide con cualquier carácter no alfanumérico ni Ad\d-\d\d-\d\d\d\d/ una fecha: dos 18-01-2009, 04-12-1997
subrayado. dígitos, guión, dos
• \0 (cero): Coincide con el carácter nulo o de fin de dígitos, guión y
cadena. No puede tener ningún dígito a continuación cuatro dígitos.
(\03 por ejemplo).
Aw\w\w\w/ cuatro caracteres java, JaVa, J4va, 3 J s
En los ejemplos de la tabla 2.6 se han escrito los caracteres alfanuméricos o
no representables como texto entre corchetes ([]). subrayados (una
contraseña por
ejemplo).
Tabla 2.6. Ejemplos de patrones con caracteres especiales.

Patrón Significado Valores que lo cumplirían Agrupación de valores


En ocasiones puede surgimos la necesidad de crear patrones
/.n/ Un carácter un, en
que puedan encontrar una coincidencia con palabras que son
seguido de
muy similares y sólo se diferencian en una pequeña parte, lo
una "n".
cual nos obligaría a crear un patrón por cada una de esas dife­
/hola\n/ "hola” seguido de hola[NUEVA LÍNEA] rencias. Por eso nos viene 'com o anillo al dedo" el uso de estas
un salto de línea. estructuras para así fusionar todo bajo un m ismo patrón.

44 45
• [xxx]: Coincide con uno de los caracteres que están entre Tabla 2.8. Ejemplos de patrones con caracteres de posición.
los corchetes. También es posible especificar un rango
de caracteres usando un guión. Por ejem plo [abe] es Patrón Significado Valores que lo cumplirían
lo mismo que [a-c], o [01234] sería equivalente a [0-4].
m "B" al inicio de Buenos días, Bocadillo
La única regla para usar este guión es que esos valores
deben ser contiguos, es decir, no podremos decir que el la línea. de tortilla...
rango es del cero al cuatro, excepto el tres. /ABu / "Bu" al inicio de Buenos días, Buenas
• [''x x x ]: El uso del circunflejo (A) dentro de un conjunto la línea. tardes...
de caracteres hace que coincida con cualquier carácter /o$/ "o" al final de Hace viento, Altavoz
salvo los que estén indicados en el conjunto. A esto se le la línea. amplificado...
conoce como conjunto complementado o negado. Aquí
/to$/ "to" al final de Hace viento, Eso está
también es posible definir un rango con el guión.
• Barra vertical (x |y): Puede coincidir con x o y, pero no a línea. alto...
con los dos. Puede ir dentro de corchetes para acortar
mejor los valores. Nota: Si necesita buscar alguno de los caracteres que se
• [\b]: Coincide con el carácter de retroceso o backspace. emplean para construir los patrones, es tan sencillo como
No lo confunda con el carácter especial \b (separador utilizar el carácter de escape antes de escribirlo. De modo que
de palabra). quedarían expresados como \A, \[ o \$, por ejemplo.

Tabla 2.7. Ejemplos de patrones con agrupación de valores. Todos estos caracteres especiales pueden combinarse e in­
Patrón Significado cluso un mismo patrón puede escribirse de distintas formas.
Valores que lo cumplirían
Por ejemplo, suponiendo que queremos crear un patrón para
/[ue]n/ "u" o "e" seguido un, en encontrar un número de dos dígitos, todas las siguientes ex­
de "n". presiones regulares serían equivalentes:
/[Aue]n/ Cualquier carácter an, Fn, 1n... /[0123456789] [0123456789]/
excepto "u" o "e" / [0-9] [0-9]/
seguido de "n". / [0-9]{2}/
/\d\d/
/cara|cruz/ "cara" o "cruz". cara, cruz /\d(2}/
/gat[a|o]/ "gat" seguido gata, gato
de "a" u "o".
2.3.2. Usar paréntesis dentro
Caracteres de posición de una expresión regular
Estos caracteres nos permiten especificar en qué parte de la
línea debe existir la coincidencia dentro de nuestro patrón. Si encerram os entre paréntesis cualquier parte de una
expresión regular causarem os que la cadena coincidente se
• Circunflejo ( A): H ace que nuestro patrón tenga que recuerde para poder recuperar su valor más tarde. Esto es
coincidir desde el inicio de la línea. Debe ir colocado útil cuando querem os utilizar los patrones para hacer reem ­
siempre al inicio del patrón. plazos en un texto utilizando parte del que ya existe, como
• $: Cumple la m isma función que el anterior pero ha­ por ejem plo buscar / (vasos)/ y sustituirlo por "posavasos"
ciendo que nuestro patrón coincida hasta la parte final ("vasos" es el valor recordado). Podem os recordar tantos va­
de la línea. Se debe añadir al final de nuestra expresión lores como queram os, utilizando una pareja de paréntesis
regular. ¿;. para cada uno de ellos. n ■11 •
Biblioteca de Sanfiag,
46
Dirección de B iblio teca* 47
Ar chivos y Museos
Así mismo, podemos aplicar alguno de los caracteres para
Patrón Significado Valores que lo cumplirían
patrones complejos a la parte delimitada por paréntesis, de
forma que su funcionalidad se aplicaría a todo el conjunto. Si /(ja)+/g¡ Palabra "ja" repetida ja, Ja, JaJa, JAJAJA,
tenemos el patrón / ( j a ) + / obtendremos coincidencias con una o más veces, sin JAjaJAja...
una o varias repeticiones del texto "ja": "ja" o "jajaja". distinguir mayúsculas
Para poder recuperar estas coincidencias, tendremos que y minúsculas y todas
escribir la siguiente expresión: sus ocurrencias.
• \x: Donde x es un entero positivo que hace referencia
al núm ero de cadena que hem os m arcado para ser No se preocupe si no consigue escribir correctamente una
recordado, contando de izquierda a derecha. expresión regular a la primera. Estas sentencias necesitan prác­
tica y aún así hay ocasiones en las que se vuelve complicado
Imaginemos que tenemos el texto "doble clic". Si le apli­
dar con el fallo. Sin embargo, son tremendamente útiles cuando
camos el patrón / ( \w+) ( \w+) / obtendremos coincidencias
están bien definidas.
con ambas palabras, puesto que buscaríamos uno o más carac­
teres alfanuméricos, seguido de un espacio en blanco y otra
vez uno o más caracteres alfanuméricos. Con esto, las partes
de caracteres alfanuméricos serán recordadas para poder ser 2.4. Expresiones regulares útiles
recuperadas m ediante \1 (doble) y \2 (clic) respectivamente.
A continuación le dejo algunos patrones, en una forma bas­
tante básica, que se suelen utilizar con frecuencia, aunque le
2.3.3. Modificadores aconsejo que cree los suyos propios para adquirir una mayor
práctica.
Una expresión regular puede llevar m odificadores o flags
para definir algunas características a tener en cuenta a la hora
de buscar coincidencias. Podemos aplicar a un patrón tantos Tabla 2.10. Expresiones regulares de uso frecuente.
modificadores como queramos y deben escribirse justo al final, Expresión regular Descripción
a continuación de la última barra (/) que delimita el patrón.
Ad{9}/ Número de teléfono.
• g: Fuerza que se sigan buscando coincidencias después
de encontrar la primera. Esto puede resultar útil cuando Ad{8}[a-zA-Z]/ Número de DNI.
queremos reemplazar la m isma cadena varias veces. Ad{2}-\d{2}-\d{4}/ Fecha (día-mes-año).
• i: Elimina la distinción entre mayúsculas y minúsculas. /([0][1 -9]| 1[0-2]): [0-5]\d:[0-5]\d/ Hora (hora:minutos:segundos
• m: Permite usar varios caracteres de posición ( Ay $) en en formato de 12 horas).
el patrón.
/([01]\d |2[0-3]): [0-5]\d:[0-5]\d/ Hora (hora:minutos:segundos
• s: Incluye el salto de línea en el comodín punto ( .) .
• x: Fuerza que los espacios sean ignorados. en formato de 24 horas).
Aw+@\w+\.\w{2,3}/ Dirección de correo electrónico.
Tabla 2.9. Ejemplos de patrones con modificadores.

Patrón Significado Valores que lo cumplirían

/javascript/i Palabra "javascript" javascript, JavaScript,


sin distinguir JAVASCRIPT
mayúsculas y
minúsculas. |

48 49
Operadores y conversión
entre tipos

3.1. Operadores en JavaScript


Los operadores nos permiten realizar cálculos o acciones
sobre las variables o datos que maneja un script, devolviendo
otro valor como resultado de dicha operación. A esos datos
utilizados se les da el nombre de operandos.
JavaScript nos proporciona una buena lista de operadores
para poder jugar con los datos.

3.1.1. Operador de asignación


Este operador, identificado por el símbolo igual (=), asigna
al operando situado a su izquierda el valor del operando que
esté a su derecha, pudiendo ser este último el resultado de un
cálculo o una expresión.
De este modo, si escribimos ennuestro código var mi Dato
= 5 ; el operador asignará el valor 5 a la variable mi Dato.
También sería posible escribir var miDato = otroDato;
copiando así el valor que tuviera la variable otroDato en la
variable miDato.
Existen más operadores de asignación pero, como en rea­
lidad son formas abreviadas de algunos operadores que ve­
remos a continuación, prefiero presentárselos en su m omento
como operadores abreviados.

3.1.2. Operadores aritméticos


Estos operadores nos permiten realizar cálculos m atem á­
ticos sencillos. Para ello, toman valores numéricos como ope­
randos y devuelven un único valor, también numérico.
O peradores sum a, resta y signo | Operación Ejemplo Resultado
Estos tres operadores se identifican mediante dos símbolos:
Suma y resta var miDato = 3 - 2 + -1; miDato vale 0
más (+) y menos (-). Según la posición en que los utilicemos
positivos
realizarán una operación u otra:
y negativos
• Si los colocamos entre dos operandos, se realiza la suma Suma y resta var miDato = 3 + 2 - -1; miDato vale 6
o resta entre ellos. positivos
• Si lo colocamos junto a un operando, se cambia el signo y negativos
de éste.
Veam os esas distintas operaciones y la form a de escri­ Operadores incremento y decremento
birlas:
Com o extensión de los operadores anteriores, existe la
posibilidad de utilizarlos para sumar (incremento) o restar
Tabla 3.1. Ejemplos de los operadores suma, resta y signo.
(decremento) una unidad al valor de un operando, escrito de
Operación Ejemplo Resultado una forma más breve. Para realizar una de estas operaciones,
debemos usar ++ para hacer un incremento y — para un de­
Suma var miDato = 3 + 2; miDato vale 5 cremento.
Resta var miDato = 3 - 2 ; miDato vale 1
Signo positivo var miDato = +7; miDato vale 7 Tabla 3.3. Incremento y decremento.

Signo positivo var miDato = 7; miDato vale 7 (operador | Operación Ejemplo Equivalencia ■
no obligatorio)
Incremento m¡Dato++; miDato = miDato + 1;
Signo negativo var miDato = -7; miDato vale -7
Decremento miDato - ; miDato = miDato -1 ;
Se pueden realizar tantas com binaciones como queramos
con estos operadores. Veamos un ejemplo de cada uno con un pequeño script:
<SCRIPT TYPE="text/javascript">
Tabla 3.2. Ejemplos de uso múltiple de los operadores suma, resta I I Declaración de variable
var miDato = 3;
y signo.
I I Incremento
Operación Ejemplo Resultado miDato++;
// Mostramos su valor
Suma y resta var miDato = 3 + 2 - 4 ; miDato vale 1 alert(miDato);
</SCRIPT>
Resta y suma var miDato = 3 - 2 + 9; miDato vale 10 <SCRIPT TYPE="text/javascript">
var miDato = 1 + 1 + 1 + 1; miDato vale 4 // Declaración de variable
Suma múltiple
var miDato = 3;
Suma positivos var miDato = 3 + +2; miDato vale 5 // Decremento
miDato vale 1 miDato— ;
Resta positivos var miDato = 3 - +2;
// Mostramos su valor
Suma positivos var miDato = 3 + -2; miDato vale 1 alert(miDato);
y negativos </SCRIPT>

Suma positivos var miDato = -3 + 2 + 6; miDato vale 5 En el primer ejemplo, la variable miDato valdrá 4 al hacer
y negativos el alert, mientras que en el segundo valdrá 2 .

52 53
O p erad o res sum a, resta y signo
Operación Ejemplo Resultado
Estos tres operadores se identifican mediante dos símbolos:
Suma y resta var miDato = 3 - 2 + -1; miDato vale 0
más (+) y menos (-). Según la posición en que los utilicemos
positivos
realizarán una operación u otra:
y negativos
• Si los colocamos entre dos operandos, se realiza la suma Suma y resta var miDato = 3 + 2 - -1; miDato vale 6
o resta entre ellos. positivos
• Si lo colocamos junto a un operando, se cambia el signo y negativos
de éste.
Veam os esas distintas operaciones y la form a de escri­ O peradores increm ento y decrem en to
birlas:
Como extensión de los operadores anteriores, existe la
Tabla 3.1. Ejemplos de los operadores suma, resta y signo.
posibilidad de utilizarlos para sumar (incremento) o restar
(decremento) una unidad al valor de un operando, escrito de
Operación Ejemplo Resultado una forma más breve. Para realizar una de estas operaciones,
debemos usar ++ para hacer un incremento y — para un de­
Suma var miDato = 3 + 2; miDato vale 5 cremento.
Resta var miDato = 3 - 2 ; miDato vale 1
Signo positivo var miDato = +7; miDato vale 7 Tabla 3.3. Incremento y decremento.

Signo positivo var miDato = 7; miDato vale 7 (operador | Operación Ejemplo Equivalencia ■ I
no obligatorio)
Incremento miDato++; miDato = miDato + 1;
Signo negativo var miDato = -7; miDato vale -7
Decremento miDato miDato = miDato -1 ;
Se pueden realizar tantas com binaciones como queramos
con estos operadores. Veamos un ejemplo de cada uno con un pequeño script:
<SCRIPT TYPE="text/javascript">
Tabla 3.2. Ejemplos de uso múltiple de los operadores suma, resta // Declaración de variable
y signo. var miDato = 3;
I I Incremento
Operación Ejemplo Resultado miDato++;
// Mostramos su valor
Suma y resta var miDato = 3 + 2 - 4 ; miDato vale 1 alert(miDato);
</SCRIPT>
Resta y suma var miDato = 3 - 2 + 9; miDato vale 10 <SCRIPT TYPE="text/javascript">
Suma múltiple var miDato = 1 + 1 + 1 + 1 ; miDato vale 4 // Declaración de variable
var miDato = 3;
Suma positivos var miDato = 3 + +2; miDato vale 5 // Decremento
miDato vale 1 miDato— ;
Resta positivos var miDato = 3 - +2;
// Mostramos su valor
Suma positivos var miDato = 3 + -2; miDato vale 1 alert(miDato);
y negativos </SCRIPT>

Suma positivos var miDato = -3 + 2 + 6; miDato vale 5 En el primer ejemplo, la variable miDato valdrá 4 al hacer
y negativos el alert, mientras que en el segundo valdrá 2 .

52 53
Además, estos operadores se pueden colocar antes o des­ // Mostramos el valor con post-incremento
pués del operando, generando resultados distintos: alert(numero++);
// Mostramos el valor con otro post-incremento
• Si los colocamos antes (prefijo), el valor del operando se alert(numero++);
modifica antes de leer su contenido. A esto se le conoce </SCRIPT>
como pre-increm ento y pre-decrem ento.
• Si lo colocamos después (sufijo), el valor del operando ¿Qué cree que ocurrirá? Si analizamos con calma el código
se modifica después de realizar obtener su contenido. veremos que el primer alert nos mostrará un 3, increm en­
A esto se le conoce como post-increm ento y post-decre- tando seguidamente el valor de la variable numero. Por ello,
mento. el segundo alert mostrará un 4 y después volverá a incre­
mentar la variable.
Puede que esto resulte un poco confuso según se lee, así Vamos ahora con un último ejemplo para reforzar nuestros
que preste atención al siguiente script: conocimientos sobre el funcionamiento de estos operadores
<SCRIPT TYPE="text/javascript"> tan traviesos:
// Declaración de variables
<SCRIPT TYPE="text/javascript">
var numl = 3;
// Declaración de variable
var num2 = 3;
var numero = 3;
// Mostramos el valor con pre-incremento
// Mostramos el valor con pre-incremento
alert(++numl) ;
alert(++numero);
// Mostramos el valor con post-incremento
// Mostramos el valor con post-incremento
alert(num2++) ;
alert(numero++);
</SCRIPT>
</SCRIPT>
A primera vista podríam os decir que el resultado obtenido ¡Buf! ¿Y ahora que saldrá? C alm a... vayamos siempre paso
en ambos casos es el mismo pero, ¿qué ocurre si ejecutamos a paso.
ese código? Aunque le parezca m entira, el prim er alert nos Con el prim er alert se incrementará la variable numero
mostrará un 4 mientras que el segundo mostrará un 3. ¿¡Cómo!? antes de ser mostrada, por lo que veremos un 4. A continua­
¿¡Por qué!?
ción volvemos a mostrar la variable, que será incrementada
después, así que verem os... ¡otro 4!
[Aplicación JavaScript] [X | [Aplicación JavaScript] (X

Operadores multiplicación y división


¿h 4 ¿h 3
| Aceptar ]
Las operaciones de multiplicación y división se representan
| Aceptar ™ ]
con un asterisco (*) y una barra (/) respectivamente. Para uti­
P re -in c re m e n to P o s t-in c re m e n to lizarlos basta con ponerlos entre dos operadores, tal y como
hemos visto con la suma y la resta.
Figura 3.1. Ejemplo con incrementos.
Tabla 3.4. Ejemplos de los operadores multiplicación y división.
En el primer caso, la variable numl es incrementada antes
Operación Ejemplo Resultado
de que alert nos m uestre su valor. Sin embargo, en el se­
gundo caso la variable num2 es increm entada después de ser Multiplicación var miDato = 6 * 2 ; miDato vale 12
mostrada. Curioso, ¿verdad? Pruebe ahora con el siguiente
script: División var miDato = 6 /2 ; miDato vale 3

<SCRIPT TYPE="text/javascript">
// Declaración de variable
Por supuesto, también se pueden encadenar varias opera­
var numero = 3; ciones con estos operadores: var miDato = 6 / 2 * 3 ,
dando como resultado un 9.
54
55
O p erad o r resto o m ódulo También sería posible usar una variable como operando
Este operador, a través del símbolo de porcentaje (%), per­ de este operador.
mite obtener el resto resultante de la división de dos operandos. <SCRIPT TYPE="text/javascript">
Este resto también es conocido como el módulo del dividendo // Declaración de variables
sobre el divisor. var numerol = 3;
var numero2 - 5;
// Suma con operador abreviado
Tabla 3.5. Ejemplos del operador resto o módulo. numerol += numero2;
// Mostramos el valor (numerol vale 8)
Ejemplo Resultado alert(numerol);
</SCRIPT>
var miDato = 6 % 2; miDato vale 0
var miDato = 7 % 2; miDato vale 1 3.1.3. Operador sobre cadenas
Este apartado será bastante corto, puesto que sólo existe un
6 L ?_ 7 |2 operador que actúe sobre las cadenas con el que se consigue
0 3 1 3 unir o concatenar dos cadenas. Se representa con el mismo
símbolo del operador aritmético de suma: más (+).
\
M ó d u lo ^ Esta coincidencia no supone un problema para JavaScript
que realizará una operación u otra en función del tipo de los
Figura 3.2. Representación del módulo. operandos: suma si son números y concatena si son cadenas.

O peradores aritm éticos abreviados Tabla 3.7. Ejemplos del operador sobre cadenas.

Como le adelanté al explicar el operador de asignación, | Ejemplo Resultado


en JavaScript es posible escribir de form a abreviada el uso var miDato = "Java" + "Script"; miDato vale
de cualquiera de estos operadores aritm éticos para hacer
"JavaScript"
nuestro código más rápido de escribir. Solam ente interviene
var miDato = "Capítulo " + "3"; miDato vale
un único operando, situado a la derecha. De este m odo po­
drem os hacer el cálculo (suma, división, etc.) y su asignación "Capítulo 3"
de un solo golpe obteniendo el m ism o resultado. En la tabla var miDato = "Im " + "pre" + "sio" + "nante"; miDato vale
3.6 podrá ver estos operadores abreviados y su equivalencia "Impresionante"
en forma "larga".
Si intentamos concatenar números con cadenas, JavaScript in­
terpreta todos los operandos como si fuesen cadenas de texto.
Tabla 3.6. Ejemplos de operadores aritméticos abreviados.
<SCRIPT TYPE="text/javascript">
Ejemplo Equivalencia // Declaración de variables
var x = 6;
var miDato += 5; var miDato = miDato + 5; // Unión de número con cadena (resultado "10 metros")
alert (10 + " metros");
var miDato -= 5; var miDato = miDato - 5;
// ünión de cadena con número (resultado "Capitulo 3")
var miDato *= 5; var miDato = miDato * 5; alert("Capitulo " + 3);
// Unión de cadena con variable número (resultado
var miDato /= 5; var miDato = miDato / 5; // "Capitulo 6")
var miDato %= 5; var miDato = miDato % 5; alert("Capitulo " + x ) ;
</SCRIPT>

56
57
3.1.4. Operadores lógicos O p erad o r O (OR)
Este operador se representa con dos barra verticales ( I I) y
Estos operadores se u tilizan para realizar operaciones devuelve un valor true si al menos uno de sus dos operandos
con dos únicos resultados posibles: verdadero (true) o falso lo son. En cualquier otro caso nos da un valor false.
(false). Esto nos será muy útil para tomar decisiones dentro
de nuestros scripts. Tabla 3.10. Funcionamiento del operador lógico O.
Los operandos que se utilicen junto con uno de estos opera­
dores serán evaluados siempre como un valor booleano, para Valor Valor Ejemplo Resultado
así poder devolver otro valor del mismo tipo. operando 1 operando 2

var x = false; var y = false; var z = x || y; z vale false


Nota: Si tiene curiosidad desde ya por saber cómo se evalúa
var x = true; var y = false; var z = x || y; z vale true
cualquier tipo de variable como un booleano, puede echar un
vistazo a algunos ejemplos en la tabla 7.1 del capítulo 7.______ var x = false; var y = true; var z = x || y; z vale true
var x = true; var y = true; v a rz = x || y; z vale true

O p erad o r NO o de negación (NO T)


Este operador se representa con el símbolo de fin de excla­ 3.1.5. Operadores condicionales
mación ( ! ) y nos permite invertir el valor del operando que o de comparación
le acompañe.
Los operadores condicionales nos servirán para comparar los
valores de sus dos operandos, devolviendo un valor booleano
Tabla 3.8. Funcionamiento del operador lógico NO o de negación.
(true o false). Junto con los operadores lógicos, son también
Ejemplo Resultado muy útiles a la hora de tomar decisiones en nuestro código.
Valor operando

var y = !x; y vale true O p erad o res de igualdad y d esig u aldad


var x = false;
var x = true; var y = !x; y vale false El operador de igualdad (==) y desigualdad (! =) nos per­
miten comprobar si los valores de dos operandos son iguales o
no, independientemente del tipo que sean dichos operandos. El
O p erado r Y (AN D ) resultado obtenido es true cuando la igualdad o desigualdad
Este operador se representa con dos símbolos ampersand se cumple y false en caso contrario.
(& &) y devuelve un valor true si sus dos operandos también
lo son, o un valor f a l s e en otro caso. Advertencia; No confundir el operador de asignación (=) con
el de igualdad (==), ya que su función es bien distinta.
Tabla 3.9. Funcionamiento del operador lógico Y.
Tabla 3.11. Funcionamiento de los operadores de igualdad
Valor Ejemplo Resultado
Valor y desigualdad.
operando 1 operando 2
Valor Valor Ejemplo Resultado
var y = false; var z = x && y; z vale false operando 1 operando 2
var x = false;
var y = false; var z = x && y; z vale false
var x = true; var x = 5; var y = 5; var z = x == y; z vale true
var y = true; var z = x && y; z vale false
var x = false; var x = 5; var y = 5; var z = x != y; z vale false
var y = true; var z = x && y; z vale true var x = 9; var y = 5; var z = x == y; z vale false
var x = true;

58 59
Valor Valor Ejemplo Resultado
Conforme a la tabla 3.12, puede com probar cómo hemos
operando 1 operando 2 obtenido los mismos resultados salvo en los dos últimos ejem­
plos donde, con estos operadores estrictos, sí se ha tenido en
var x = 9; var y = 5; var z = x != y; z vale true cuenta el tipo de datos para los valores 5 y "5" (número y ca­
var x = "hola"; var y = "hola"; var z = x == y; z vale true
dena respectivamente).
var x = "hola"; var y = "hola"; var z = x != y; z vale false Operadores mayor y menor
var x = "libro"; var y = "hola"; var z = x == y; z vale false
El operador mayor (>) nos devuelve un valor true si el
var x = "libro"; var y = "hola"; var z = x != y; z vale true operando de la izquierda tiene un valor estrictamente mayor
var x = 5; var y = "5"; var z = x == y; z vale true que el de la derecha. El operador m enor (<), por el contrario,
var x = 5; var y = "5"; var z = x != y; z vale false nos devuelve true si el valor izquierdo es estrictamente menor
que el derecho.
En los dos últimos ejemplos de la tabla 3.11 el número 5
y la cadena "5" tienen el mismo valor para JavaScript por la Nota: Si ambos valores coincidiesen, se devolvería f a l s e y a
conversión de tipos que éste realiza (cosa que verem os más que un valor no es estrictamente mayor o menor que el otro.
adelante en este capítulo).
Por otro lado, tenemos los operadores de igualdad estricta En el caso de tener operandos numéricos creo que el resul­
(===, tres signos de igual) y desigualdad estricta (! ==), que tado de la comparación está claro, pero si tenemos cadenas la
funcionan de la m isma manera que los que acabamos de ex­ cosa no es tan obvia. Para determinar si una cadena es m ayor
plicar, pero con la particularidad de que también comprueban o menor que otra, se comparan letra a letra (empezando por la
si los tipos de sus operandos coinciden o no. Por tanto, se izquierda) hasta encontrar una diferencia entre las dos cadenas.
obtiene un valor true cuando el valor y el tipo cum plen la Para comparar dos letras se siguen estas reglas:
igualdad o desigualdad, y valor false en caso contrario. 1. Las mayúsculas son menores que las minúsculas ("A"
Veamos los mismos ejemplos que la tabla 3.11 pero aplicando es menor que "a").
estos nuevos operadores.
2. Las primeras letras del abecedario son menores que las
últimas ("a" es menor que "c").
Tabla 3.12. Funcionamiento de los operadores de igualdad 3. Los números (expresados como cadena) son menores
y desigualdad estricta.
que las letras ("6 " es menor que M
A").
Valor Valor Ejemplo Resultado
operando 1 operando 2 “ 6 ” < “A” < “ a ” < “ C ”

var x = 5; var y = 5; var z = x === y; z vale true Menor --------------------- Mayor


var x = 5; var y = 5; var z = x !== y; z vale false Figura 3.3. Orden en la comparación de cadenas.
var x = 9; var y = 5; var z = x === y; z vale false
var x = 9; var y = 5; var z = x !== y; z vale true Tabla 3.13. Funcionamiento de los operadores mayor y menor.
var x = "hola"; var y = "hola"; var z = x === y; z vale true
var x = "hola"; var y = "hola"; v a rz = x !== y; z vale false Valor Valor Ejemplo Resultado
var x = "libro"; var y = "hola"; operando 1 operando 2
var z = x === y; z vale false
var x = "libro"; var y = "hola"; v a rz = x !== y; z vale true var x = 5; var y = 9; var z = x > y; z vale false
var x = 5; var y = "5"; var z = x === y; z vale false var x = 5; var y = 9; var z = x < y; z vale true
var x = 5; var y = "5"; var z = x !== y; z vale true var x = 9; var y = 5; var z = x > y; z vale true

60 61
Introducción al sistem a binario
Valor Valor Ejemplo Resultado
operando 1 operando 2 Antes de comenzar a listar los operadores, creo que de­
bemos hacer esta pequeña introducción al mundo del sistema
var x = 9; var y = 5; var z = x < y; z vale false binario para que pueda comprender bien todas las operaciones
var x = 5; var y = 5; var z = x > y; z vale false y ejemplos.
v a rx = 5; var y = 5; var z = x < y; z vale false Por si le 'suena a chino', un bit (Binary diglT) es un dígito del
sistema binario (base 2 ), que únicamente toma los valores cero
var x = "hola"; var y = "Hola"; var z = x > y; zvale true("h"
(0) o uno ( 1 ). La agrupación de bits representa un número.
i mayor que "H")
Para representar un número decimal en binario debemos
var x = "hola"; var y = "adiós"; var z = x > y; zvale true ("h" dividir primeramente ese número entre la base (2 en este caso) y
mayor que "a") después dividir repetidamente los cocientes resultantes entre la
var x = "hola"; var y = "adiós"; var z = x < y; z va le fa ls e base (2 ), hasta que dicho cociente sea cero (no se pueden hacer
("a" menor que más divisiones). Los restos de todas estas divisiones serán los
nh") que formen los bits del número binario. Veamos un rápido
var x = "hola”; var y = "hoy"; var z = x > y; zvale false ("I" ejemplo de cómo convertir el número decimal 13 en binario:
menor que "y")
var x = "hola"; var y = "hoy"; var z = x < y; z vale true y("y"
y 13 L_2__
mayor que "I") 1 6 L_2__
0 3 L2
Tam bién existe una variación de estos operadores que - 11 L_2
añade la operación de igualdad a la comparación para el caso Bits ~ ” 1 0
de encontram os con valores iguales. Con ellos podremos de­
terminar si un operando es mayor, o igual (>=), o menor, o Figura 3.4. Conversión de decimal a binario.
igual (<=) que el otro.
Por tanto, el número 13 en binario se representa con los bits
1101 (se empieza por el último resto obtenido).
Tabla 3.14. Funcionamiento de los operadores mayor, o igual
Para realizar la conversión inversa (binario a decim al),
y menor o igual.
debe ver la posición de los bits com o exponentes de la base
Valor Valor Ejemplo Resultado (2 ), siendo cero la posición del bit situado más a la derecha
operando 1 operando 2 representando la potencia 2o. El número decimal se obtiene
sumando todas las potencias mientras que el valor del bit (1
var x = 5; var y = 9; var z = x >= y; z vale false
ó 0 ) correspondiente indica si debe incluirse esa potencia en
var x = 5; var y = 9; var z = x <= y; z vale true la suma. Veamos esto mejor con un ejemplo, convirtiendo a
var x = 5; var y = 5; var z = x >= y; z vale true decimal el núm ero binario 1101 anterior:
var x = 5; var y = 5; var z = x <= y; z vale true
Bits 1 1 0 1
Posición bit
3.1.6. Operadores sobre bits o binarios (exponente)
3 2 1 0

Potencia 23 22 - 2o
En este apartado tratarem os los operadores que utilizan
operandos expresados en sistema binario (unos y ceros). Si Valor potencia 8 4 0 1
esto le "suena a chino', no se preocupe que por el mismo precio
también incluimos una pequeña explicación de este sistema. Figura 3.5. Conversión de binario a decimal.

62 63
Si sumamos los valores de las potencias (8 + 4 + 0 + 1) obte­ Por último, los operadores binarios de JavaScript repre­
nemos el número decimal equivalente, que es 13. La potencia sentan cada número con 32 bits (31 para el número y 1 para el
21 no se incluye ya que el valor del bit en esa posición es 0 . signo). En caso de que un núm ero no ocupe los 31 bits, se repite
Debe saber que para poder representar, tanto los números el bit de signo en esos bits n o usados para que el complemento
negativos como positivos, se reserva el bit situado más a la iz­ a dos siga funcionando. De este modo el número decimal 13
quierda para indicar el signo (0 para los positivos y 1 para los (01101 en binario) tendrá 28 bits a 0 a la izquierda (el bit de
negativos). De modo que para el caso del núm ero binario 1101 signo y 27 réplicas) quedando como 000000000000000000000
(13 en decimal) su representación con signo sería 01101. 00000001101. En el caso del decim al -13 (10011) se tendrán 28
Desgraciadamente, tal y como maneja JavaScript los números bits a 1 (signo y 27 réplicas) quedando expresado como 11111
binarios, interpretar un número positivo o negativo no es tan 111111111111111111111110011.
sencillo como mirar el bit situado más a la izquierda y calcular el Para darles más claridad a los ejemplos, se omiten las ré­
decimal equivalente con los bits restantes (-13 no es 11101). Para plicas del signo siempre que se pueda.
convertir un positivo en negativo o lo contrario existen varios mé­
todos, pero JavaScript utiliza el que se conoce como complemento Operador de negación o complementación (NOT)
a dos, que consiste en aplicar al número dos operaciones:
Este prim er operador b in ario , com o hem os avanzado
1. Invertir el valor de cada bit que form a el número, es hace unas líneas, nos perm ite invertir el valor de cada bit que
decir, cambiar los unos por ceros y viceversa. Esta ope­ forma un número, cam biando los unos por ceros y viceversa.
ración se conoce como negación o com plem entación y El símbolo que lo representa es la tilde o virgulilla (~) y debe
la veremos como un operador de JavaScript. ir colocada delante del núm ero.
2. Se suma 1 al resultado de la operación anterior.
Advertencia: Este operador no calcula el valor negativo
Procedamos a ver cómo se representa entonces el número
de un número, sino su complemento (bits invertidos). Los
decimal -13 a partir de su positivo en binario (01101):
números negativos en JavaScript se obtienen mediante el
complemento a dos.
Bits 00 11 1 10 0 1 1
En el siguiente ejemplo, veremos cuál es el resultado de
Bits invertidos 11 |00 0 11 0 0 complementar el número decim al 13:
_____ +
Número 1 00 00 0 00 ¡ 11 p
Bit signo Bit 3 Bit 2 Bit 1 Bit 0 Número decimal
Resultado suma 11 00 0 11|T~
1
0 1 1 0 1 13
Figura 3.6. Conversión de número binario positivo en negativo. 1 0 0 1 0 -14

De este modo vemos que el número decim al -13 se repre­ Como puede ver, el valor obtenido no es -13 sino el com ­
senta en binario como 10011 en com plem ento a dos. plemento de 13, que es -14. Ahora podrá darse cuenta de por
Si va a utilizar los operadores binarios con frecuencia le qué hay que sumar 1 al utilizar el com plem ento a dos para
aconsejo que se documente de forma más amplia acerca del obtener el negativo de un número.
manejo de número binarios, puesto que aquí se ha expuesto lo
más básico para que pueda comprender los ejemplos. Operador Y (AND)

Nota: Las operaciones con números binarios se realizan bit a El comportamiento de este operador es el m ismo que el
bit y no con números completos, por lo que el resultado será la operador lógico Y (&&), salvo que éste se represente con un
combinación de cada operación individual a nivel de bit. único ampersand (&) y nos devuelva un 1 cuando los dos bits
que se comparan son tam bién un 1 .

64 65
Tabla 3.15. Funcionamiento del operador binario Y. Veam os como ejemplo el resultado que nos presenta la
operación 5 |3:
1 Valor bit 1 Valor bit 2 Resultado

0 0 0 0 1 0 1
1 0 0
0 0 1 1
0 1 0
0 1 1 1
1 1 1
Figura 3.8. Ejemplo del operador binario O.
Recuerde que las operaciones se hacen bit a bit y el resul­
tado de cada operación individual se alm acena en la misma Esta vez, el resultado de la operación nos ha dejado un 0
posición. Veam os com o ejem plo el resultado que ofrece la en la posición de la izquierda y el resto con 1. Esto nos da el
operación 5&3: número decimal 7.

Operador O exclusivo (XOR)


5 0 1 0 1
Este operador se representa mediante el acento circunflejo
3 0 0 1 1 (A) y nos devuelve un 1 cuando únicamente uno de los bits
0 0 0 1 también es un 1 .

Figura 3.7. Ejemplo del operador binario Y. Tabla 3.17. Funcionamiento del operador binario O exclusivo.
Valor bit 1 Valor bit 2 Resultado
Como ha podido observar, el resultado de aplicar el ope­
rador Y a los bits de la derecha ha dado como resultado un 1, 0 0 0
mientras que en el resto ha sido m i 0. Esto nos ha dejado una
1 0 1
secuencia nueva de bits que representa el número uno.
0 1 1
Operador O (OR) 1 1 0
Al igual que ocurre con el operador binario Y (&), este tam ­
bién se comporta como su análogo lógico ( I I ) , representándose Veam os com o ejemplo el resultado que nos presenta la
con una barra vertical ( |) y devolviendo un 1 cuando alguno operación 5 A3:
de los dos bits que se comparan es también un 1 .
5 0 1 0 1
Tabla 3.16. Funcionamiento del operador binario O.
3 0 0 1 1
Valor bit 1 Valor bit 2 Resultado
Resultado (6) 0 1 1 0
0 0 0
Figura 3.9. Ejemplo del operador binario O exclusivo.
1 0 1
0 1 1 Tanto el bit de la izquierda como la derecha se han conver­
1 1 1 tido en un 0 , dejando un 1 en las posiciones intermedias dando
lugar al número 6 .

66 67
Habrá notado que los resultados no tienen mucha lógica 11 0 1 0 1 1
desde el punto de vista de núm eros decimales (5 |3 devuelve I
«2
7). No se preocupe ya que rara vez se analiza el resultado de
Resultado (44) 0 1 0 1 1 0 0
esta forma. Normalmente se mira con detenimiento el resultado
obtenido en las posiciones de los bits (por ejemplo, si hay un
Relleno de ceros
1 en la posición 3).

-11 1 0 1 0 1 I
O p erad ores de d esplazam ien to
«2
Estos operadores van acompañados de dos operandos: el Resultado (-44) 1 0 1 0 1 0 0
número cuyos bits se van a desplazar y la cantidad de posi­
ciones que se quieren desplazar esos bits, representado por Relleno de ceros
un núm ero entero. La dirección en la que debe realizarse el Figura 3.10. Ejemplos de desplazamiento a la izquierda.
desplazamiento la indica el operador, de modo que tenemos
los siguientes: <SCRIPT TYPE="text/javascript">
// Declaración de variable
• Desplazamiento a la izquierda ( « ) : se encarga de des­ var numero = 11;
plazar los bits hacia la izquierda el número de posiciones // Desplazamiento a la derecha con propagación
indicado, rellenando con ceros los espacios de la derecha / / d e signo
resultantes de este desplazamiento. alert(numero » 2);
• Desplazamiento a la derecha con propagación de signo // Asignación de valor
numero = -11;
( » ) : desplaza los bits hacia la derecha tantas posiciones
// Desplazamiento a la derecha con propagación
como hayamos indicado, descartando los bits que sobran // de signo
por la derecha y conservando el signo. Para conservar alert(numero » 2);
el signo lo que se hace es repetir el bit de signo por la <SCRIPT>
izquierda tantas veces como desplazamientos hayamos
hecho.
• Desplazamiento a la derecha con relleno de ceros ( » > ) : 11 0 1 0 1 1 1
realiza la m ism a operación que el anterior pero re­ »2
llenando con ceros los espacios de la izquierda y sin 0 0 0 1 0 —1
conservar el signo. El resultado en los números positivos
es el mismo que con el operador » . Conservación signo

Veamos ahora unos ejemplos con cada operador, para com­ 1 0 1 0 1


prender su funcionamiento::
» 2
<SCRIPT TYPE="text/javascript"> 1 1 1 0 1
// Declaración de variable
var numero = 11; Conservación signo
// Desplazamiento a la izquierda
alert(numero « 2); Figura 3.11. Ejemplos de desplazamiento a la derecha
// Asignación de valor con propagación de signo.
numero = -11;
I I Desplazamiento a la izquierda <SCRIPT TYPE="text/javascript">
alert(numero « 2); // Declaración de variable
<SCRIPT> var numero = 11;

68 69
II l>i*r¡|)l.r/.fimi«nto a la derecha con relleno Tabla 3.18. Ejemplos de operadores sobre bits abreviados.
// de ceros
.ilert (numero » > 2); 1 Ejemplo Equivalencia
I I Asignación de valor
numero = -11; var a &= 5; var a = a & 5;
// Desplazamiento a la derecha con relleno var a |= 5; var a = a | 5;
// de ceros
var a A= 5; var a = a A 5;
alert (numero » > 2);
<SCRIPT> var a « = 2; var a = a « 2;
var a » = 2; var a = a » 2;
0 1 0 1 1 var a » > = 2; var a = a » > 2;
»> 2
0 0 0 1 0 3.1.7. Operadores especiales
Relleno de ceros JavaScript posee una serie de operadores que no encajan en
las categorías anteriores ya que no realizan un cálculo sobre
los datos.
-11 111111111111111111111111111 1 0 1 0 1 — I

»> 2 O p e rad o r condicional


Resultado
(1073741821) 0 0 1 0 1
111111111111111111111111111 _ l

Estamos frente al único operador que tiene tres operandos


Relleno de ceros escribiéndose de la siguiente forma:
Figura 3.12. Ejemplos de desplazamiento a la derecha con relleno <SCRIPT TYPE="text/javascript">
de ceros. // Operador condicional
operando_l? operando_2 : operando 3;
</SCRIPT>
Puede que le choque esa fila de unos del últim o ejem plo.
La explicación está en la breve introducción al sistem a b i­ El operando 1 es en realidad una condición que corresponde
nario, escrita hace unas páginas, donde se dijo que estos a una expresión que puede valer true o false. En base a él
operad ores m an ejan los n úm eros com o con ju ntos de 32 este operador devuelve el operando 2 si dicha condición sé
bits y que se om itiría la réplica del signo siem pre que fuera cumple, o el operando 3 en caso contrario.
posible para que su lectura fuera m ás fácil. En el ejem plo, Para añadir mayor claridad al código, la expresión del ope­
el núm ero -11 representado con todos sus bits queda como rando 1 se suele encerrar entre paréntesis.
11111111111111111111111111110101 (27 réplicas de signo). Veamos cómo utilizar este operador dentro de un script:
Al desplazar los bits dos posiciones a la derecha y rellenar <SCRIPT TYPE="text/javascript">
con ceros obtenem os el núm ero binario 001 1111 1 1 1 1 1 1 1 1 1 // Declaración de variables
1111111111111101. var edad = 16;
var mayoriaEdad;
O peradores sobre bits abreviados // Uso operador condicional
mayoriaEdad = (edad >= 18)? "sí" : "no";
Com o ya ocurría con los operadores aritm éticos, existe // Mostramos su valor
también la posibilidad de escribir los operadores sobre bits de alert(mayoriaEdad);
</SCRIPT>
una forma abreviada, de modo que la operación binaria y su
asignación pueden realizarse a través de un solo operador de Si escribimos este código, y lo ejecutamos en nuestro nave­
asignación, como puede ver en la tabla 3.18 que mostram os a gador, veremos cómo la variable mayoriaEdad recibe el valor
continuación. "no" ya que la expresión (edad >=18) toma valor false

70 71
O p erad o r com a En la tabla 3.19 podremos ver los tipos que puede devolver
este operador, junto a un pequeño ejemplo.
Este operador ( , ) se coloca entre dos operandos con la
única finalidad de que ambos sean evaluados y que el valor
Tabla 3.19. Tipos devueltos por el operador typeof.
del segundo sea devuelto por el operador.
Veremos, en el siguiente capítulo, su uso dentro de los bu­ Tipo devuelto Operando esperado Ejemplo
cles for, ya que es el sitio donde se emplea principalmente.
"number" Cualquier número typeof(5) o
O p e rad o r void (entero o real) typeof(1 + 2)
"boolean" Valor booleano typeof(true) o
Cuando se usa este operador junto con una expresión, lo
typeof(1 < 2)
que se consigue es que dicha expresión sea ejecutada pero sin
devolver ningún valor, es decir, la operación se realiza pero el "string" Cadena de texto typeoffhola") o
resultado no puede ser almacenado ya que se descarta. typeof("ho" + "la")
La expresión que evalúa este operador puede ser escrita a con­ "function" Función u objeto typeof(alert)
tinuación del mismo o usando paréntesis, de manera que void predefinido
miExpresion es lo mismo que void (miExpresion). "object" Objeto no predefinido typeof(miObjeto)
Veamos qué pasa si lo utilizam os dentro de un script: "undefined" Operando no typeof(miVariable-
<SCRIPT TYPE="text/javascript"> inicializado Nueva)
// Declaración de variable
var suma;
// Oso operador void Nota: Si quiere comprobar el tipo de un operando tenga en
suma = void(l + 2); cuenta que está manejando cadenas. Por tanto debe escribir
// Mostramos su valor algo como t y p e o f (5 ) == "n u m ber".
alert(suma);
// üso operador suma
suma = 1 + 2;
Operadores sobre objetos
// Mostramos su valor Por últim o, existen otros operadores en JavaScript que se
alert(suma);
utilizan para manejar objetos. En este capítulo simplemente
</SCRIPT>
los nombrarem os, ya que se explicarán con más detalle en el
El resultado de ejecutar este código es que la expresión 1 + capítulo correspondiente a los objetos.
2 es evaluada, pero su valor no es devuelto a la variable suma,
por lo que en el prim er alert ésta tiene valor undef ined • El punto (.): Sirve para obtener el valor de una propiedad
dado que todavía no ha sido inicializada. Sin embargo, en el o ejecutar un método del objeto que le precede.
segundo alert vemos que tiene valor 3 como resultado de la • Los corchetes ( [ ] ): Sirven para acceder al valor de una
operación de suma realizada justo antes. propiedad o método del objeto que le precede.
• new : Nos permite crear una instancia del objeto que
O p erad o r typ e o f indiquemos.
• delete : Se utiliza para borrar tina propiedad de una
M ediante este operador podrem os conocer el tipo de dato instancia.
del operando que pongam os a continuación. Este operando • i n : Nos perm ite saber si una propiedad existe en el
corresponde a una expresión, que no es evaluada, y su tipo se objeto que indiquemos.
devuelve como una cadena de texto. • instanceof: N os dice si la instancia especificada
Al igual que ocurre con el operador void, el operando corresponde al objeto que indiquemos.
puede ir encerrado entre paréntesis o no, siendo lo mismo • this: Sirve para referirse a un objeto como sustituto de
typeof miOperando que typeof (miOperando). su nombre.

72 73
3.1.8. Precedencia de los operadores Aquí puede jugar un papel importante el uso de los parén­
tesis, ya que con ellos podremos alterar el orden de precedencia
Tod os los o p erad ores que h em os v isto h asta ahora de los operadores. Por ejemplo, si escribimos la expresión (5
pueden utilizarse conjuntam ente y las veces que se necesiten. * 2) - 1 obtendrem os como resultado un 9, mientras que si
Consecuentemente, es necesario establecer un orden de ejecu­ dejamos la expresión como 5 * (2 - 1 ) tendremos un 5. Esto
ción o precedencia entre ellos ya que, por ejemplo, la expresión es así porque primero se ejecuta la parte que está entre parén­
5 * 2 - 1 puede ser interpretada de distintas maneras: tesis al tener m ayor precedencia que el resto de operadores.

1. Si consideramos que primero se ejecuta la resta (2 - 1 )


y, con ese resultado, se ejecuta después la multiplicación 3.2. Conversión entre tipos
(5 * 1), entonces tenemos el valor 5 como resultado.
2. Si ejecutamos prim ero la multiplicación (5 * 2 ) y a
Como habrá podido ver en algunos de los ejemplos del
continuación, con ese resultado, la resta (1 0 - 1 ),
apartado anterior, a veces es posible combinar dos operandos
entonces tendremos como resultado el valor 9.
de distinto tipo sin obtener ningún tipo de error por ello. ¿Cómo
¿Cuál es la interpretación válida? Si miramos la tabla 3.20 sabe JavaScript que, por ejemplo, la cadena "5" puede ser inter­
nos daremos cuenta de que el resultado correcto es 9, ya que pretada de la misma manera que el número 5? Esto es posible
la multiplicación tiene m ayor precedencia que la resta. gracias a la conversión interna entre tipos que posee JavaScript,
pudiendo ser de dos tipos: implícita y explícita.
Tabla 3.20. Precedencia de operadores.
3.2.1. Conversión implícita
Precedencia Operadores ¡I
Esta conversión se realiza automáticamente por JavaScript
11 •ü cuando detecta que los operandos que recibe un operador
2 () new tienen distinto tipo. Esta conversión no siem pre es posible
3 ! — (signo menos) + (signo más) ++ ("hola" no tiene equivalencia como número) así que en oca­
- typeof void delete siones el resultado es impredecible (¡JavaScript hace lo que
4 * /% puede!).
El único operador que tiene un comportamiento m ás es­
5 + (suma) - (resta)
pecial es la suma (+) puesto que ya hemos visto que puede
6 « » »>
utilizarse tanto para sumar números como para concatenar
7 < < = > > = in instanceof cadenas. Si en una m isma suma utilizam os valores n u m é­
8 == ¡- === i== ricos y cadenas, JavaScript siempre lo va a interpretar como
9 & una concatenación de cadenas. Pongamos como ejem plo el
A
siguiente código:
10
<SCRIPT TYPE="text/javascript">
11 |
// Declaración de variables
12 && var cadena = "6”;
13 var numero = 4 ;
II // Primera operación
14 ?; alert(cadena + numero);
15 =+= -= *= /= %= &= A= |= « = » = // Segunda operación
»>= alert(numero + cadena);
// Tercera operación
16 » alert(numero + numero);

74 75
// Cuarta operación
En las dos operaciones, gracias a la intervención de la con­
alert(cadena + cadena);
</SCRIFT>
versión explícita, el resultado es el mismo: el núm ero 10. Si no
utilizásemos estas funciones, JavaScript aplicaría la conversión
En las dos primeras operaciones, el resultado será una ca­ implícita explicada en el apartado anterior, dándonos como
dena ("64" y "46" respectivamente). En la tercera, como todos resultados las cadenas "64" y "46".
los operandos son números, el resultado será un número (8 ). Para terminar, me gustaría recordarle que en JavaScript las
Finalmente, en la última operación, obtendremos de nuevo variables no tienen un tipo definido, por lo que puede alm a­
una cadena (" 6 6 "). cenar el resultado de una conversión en la m ism a variable sin
En el resto de operaciones aritméticas, las cadenas inten­ provocar ningún error en su código.
tarán ser convertidas en un número para poder devolver un
<SCRIPT TYPE="text/javascript">
valor numérico. Por ejemplo: // Declaración de variable
<SCRIPT TYPE="text/j avascript"> var cadena = "6";
// Declaración de variables // Conversión explícita
var cadena = "6"; cadena = parselnt(cadena);
var numero = 2; I I Mostramos el valor (número 6)
// Primera operación alert(cadena);
alert(cadena - numero); // mostrará un 4 </SCRIPT>
// Segunda operación
alert(numero * cadena); // mostrará un 12
// Tercera operación
alert(cadena / numero); // mostrará un 3
</SCRIPT>

Otro pequeño caso especial ocurre cuando se intenta trans­


formar un valor booleano en un número. Para este tipo de
datos, los valores true se interpretan como el número 1 y los
false como un 0 .

3.2.2. Conversión explícita


Dado que hay ocasiones en que la conversión implícita no
ofrece un resultado predecible ni deseado, es preciso que inter­
venga la mano del programador para realizar estas conversiones
cuando sea necesario. Para ello, dispone de las funciones prede­
finidas parselnt y parseFloat, las cuales están detalladas
en el capítulo 5, dedicado a las funciones, aunque le dejaré un
pequeño ejemplo para que vea cómo influye en el resultado:
<SCRIPT TYPE="text/javascript">
// Declaración de variables
var cadena = "6";
var numero = 4;
// Primera operación
alert(parselnt(cadena) + numero);
// Segunda operación
alert(numero + parselnt(cadena));
</SCRIPT>

76 77
Estructuras de control

Los ejemplos vistos hasta ahora han sido bastante "sosillos"


ya que nos hem os limitado a ejecutar instrucciones en orden
secuencial. No se desanime, JavaScript no nos va a decepcionar
y por ello nos brinda una colección de estructuras de control
con las que podrem os adaptar nuestro código a las múltiples
necesidades que nos vayan surgiendo, permitiéndonos ser un
poco más dueños de las instrucciones que se van a ejecutar
mediante la toma de decisiones (por ejemplo, si una variable
sobrepasa un valor) o repetir una operación varias veces con
la inclusión de bucles (realizar la suma de los núm eros que
van del 1 al 30).
Todas las instrucciones que se quieran ejecutar dentro de una
estructura de control deben ir encerradas entre llaves ( { } ).
<SCRIPT TYPE="text/javascript">
estructura-de-control {
// Mis instrucciones
}
</SCRIPT>

Truco: En JavaScript no es obligatorio usar las llaves si


nuestro bloque consta de una única instrucción.

Además, toda estructura de control puede ir anidada dentro


de cualquier otra estructura, de forma que sería posible, por
ejemplo, tomar una decisión dentro de un bucle o ejecutar un
bucle dentro de otro (veremos que es útil para recorrer los
datos de una tabla).
Pasemos ahora al detalle de cada una de estas estructuras,
agrupadas por categorías: condicionales, de bucle y, por último,
de manipulación de objetos.

79
4.1. Estructuras condicionales <SCRIPT TYPE="text/javascript">
// Declaración de variable
var edad = 19;
Este tipo de estructuras evalúan una condición que, de // Sentencia if - else
cum plirse, perm itirán que se ejecute su bloque de instruc­ if (edad >=1 8 ) {
ciones asociado. En caso de no cumplirse dicha condición el alert("Soy mayor de edad");
bloque tampoco se ejecutará, por tanto es como si esa porción 1 else {
de código no existiera. alertf'No soy mayor de edad");
}
</SCRIPT>
4.1.1. Sentencia if -else
Si ejecutamos este script veremos en nuestra pantalla el men­
La sentencia i f ejecuta su bloque de instrucciones si la saje "Soy mayor de edad". Esto es así puesto que la condición
condición que la sigue se cumple, esto es, si la condición es (edad >=18) se cumple, quedando descartado el bloq u e de
verdadera. La sintaxis básica sería esta: la sentencia else. Si la edad fuese, por ejemplo, 13 entonces
<SCRIPT TYPE="text/javascript">
veríamos el mensaje "No soy mayor de edad".
// Sentencia if Si recuerda el operador condicional explicado en el capítulo
if (condición) { anterior, verá que existe una gran similitud con esta estructura
// Mi bloque de instrucciones de control. Fíjese cómo podría escribirse el ejem plo anterior
} usando solamente el operador condicional:
</SCRIPT>
<SCRIPT TYPE="text/javascript">
Ilustrado con un pequeño ejemplo, quedaría así: // Declaración de variables
var edad = 19;
<SCRIPT TYPE="text/javascript">
var mensaje;
// Sentencia if con condición verdadera
// Operador condicional
if (5 > 2) {
mensaje = (edad >= 18)? "Soy mayor de edad" : "No soy
// Mi bloque de instrucciones
mayor de edad";
} // Mostrar el mensaje
// Sentencia if con condición falsa
alert(mensaje);
if (5 > 9) {
</SCRIPT>
/ / M i bloque de instrucciones
} El resultado obtenido es exactamente el mismo. Ú nicam ente
</SCRIPT>
necesitamos almacenar primero el texto que devuelve el operador
O pcionalm ente podrem os usar la sentencia e l s e com bi­ dentro de una variable en vez de mostrarlo directam ente.
nada con una sentencia i f para ejecutar otro bloque en caso También es posible encadenar varias sentencias i f - else
de que la condición no se cumpla. El resultado de la unión de si necesitamos evaluar distintas condiciones.
ambas es que siem pre se ejecute uno (y sólo uno) de los dos <SCRIPT TYPE="text/javascript">
bloques. Veam os la sintaxis si utilizam os ambas sentencias: // Declaración de variable
var semáforo = "verde";
<SCRIPT TYPE="text/javascript">
// Sentencias if - else
// Sentencia if - else
if (semáforo == "rojo") {
if (condición) f
alert("Stop");
/ / M i bloque de instrucciones (condición verdadera)
} else if (semáforo =¡= "ámbar") {
} else {
alert("Precaución");
// Otro bloque de instrucciones (condición falsa)
} else if (semáforo == "verde") {
}
alert("Adelante");
</SCRIPT>
}
Quizá vea más clara esta explicación mediante un ejemplo: </SCRIPT>

80 81
En este script se irán com probando una a una todas las 75, cosa que esta vez no se cumple. Por tanto, se ejecutará fi­
condiciones hasta que se encuentre alguna que concuerde con nalmente el bloque de la sentencia else anidada, dando como
el valor de la variable semáforo. En nuestro caso se cum­ resultado el mensaje "Caro". El script seguiría ejecutando el có­
plirá la última condición haciendo que se m uestre el mensaje digo que hubiese a continuación del if-else principal dado
"Adelante". que se ha entrado en un bloque de instrucciones.
En estos casos la sentencia el se final tam bién es opcional,
aunque es m uy útil para ejecutar unas instrucciones por de­
fecto, es decir, cuando no se cumple ninguna de las condiciones 4.1.2. Sentencia switch - case
previas.
Esta otra sentencia evalúa una expresión que puede tener
<SCRIPT TYPE="text/javascript"> múltiples valores (opciones) posibles.
// Declaración de variable
La sentencia principal es el switch, que va acompañada
var semáforo = "blanco";
// Sentencias if - else de la expresión a evaluar. Dentro de ella habrá sub-bloques,
if (semáforo == "rojo") { identificados por la palabra reservada case, para cada uno de
alert("Stop"); los posibles valores que puede tomar la expresión evaluada,
} else if (semáforo == "ámbar") { y que contendrán las instrucciones a ejecutar si el valor de la
alert("Precaución"); expresión coincide con él. Cada uno de estos sub-bloques case
) else if (semáforo = "verde") { no se delimita con las llaves que hemos visto hasta ahora, sino
alert("Adelante");
que se debe hacer con dos puntos ( : ) al comienzo y la sentencia
) else {
alert("¡Este color no es de un semáforo!"); break al final.
} Una vez ejecutadas las instrucciones de un case, se fi­
</SCRIPT> naliza la sentencia switch ignorando el resto de opciones.
Recapitulando, la sintaxis queda así:
Tam bién sería posible anidar sentencias if-else dentro
de otras: <SCRIPT TYPE="text/j avascript">
// Sentencia switch-case
<SCRIPT TYPE="text/javascript"> swicth (expresión) {
// Declaración de variable case valorl:
var precio = 100; // Bloque de instrucciones para valorl
// Sentencias if - else anidadas break;
if (precio > 5 0 ) { case valor2:
if (precio < 75) { // Bloque de instrucciones para valor2
alert("Normal"); break;
) else {
alert("Caro"); }
) </SCRIPT>
} else {
alert("Barato"); Para aclarar el funcionamiento, veamos esta nueva sen­
} tencia mediante el ejemplo del semáforo que utilizamos an­
// Resto del código teriormente:
</SCRIPT>
<SCRIPT TYPE="text/javascript">
Ejecutando este código, entraríamos inicialmente dentro del // Declaración de variable
var semáforo = "verde";
bloque del primer i f, ya que la condición se cumple (precio
// Sentencia switch
> 50), descartando por tanto el bloque de la sentencia else. switch (semáforo) {
Dentro de ese prim er i f , nos encontram os de nuevo con otro case "rojo":
if que evalúa si el valor de la variable precio es menor que alert("Stop");

82 83
break;
var semáforo = "ámbar";
case "ámbar":
// Sentencia switch
alert("Precaución");
switch (semáforo) {
break;
case "rojo":
case "verde":
alert("Stop");
alert("Adelante");
case "ámbar":
break;
alert("Precaución");
)
case "verde":
</SCRIPT>
alert("Adelante");
Un poco más claro, ¿verdad? El resultado de ejecutar este )
código es exactamente el mismo que con las sentencias i f - </SCRIPT>
else: se mostraría el m ensaje "Adelante". ¿Qué mensaje aparece en su pantalla? En principio espe­
A l igual que ocurre con el if, tam bién es posible indicar ramos que sólo aparezca el mensaje "Precaución" correspon­
un conjunto de instrucciones que se ejecuten por defecto diente al valor "ámbar" pero, sin embargo, también aparece
cuando la expresión no coincide con ninguna de las opciones. también el mensaje "Adelante” a pesar de que el valor de la
Esta operación se hace añadiendo un nuevo sub-bloque con variable no es "verde".
la palabra reservada default que va norm alm ente en la Por tanto, debemos tener un poco de cuidado delimitando
última posición. correctamente los bloques case si no queremos obtener un
<SCRIPT TYPE="text/javascript"> resultado que no es el esperado. No obstante, la omisión de la
// Declaración de variable sentencia break puede tener sentido si en su código necesita
var semáforo = "blanco"; ejecutar las mismas instrucciones para un conjunto de valores.
// Sentencia switch
Veamos un caso práctico:
switch (semáforo) {
case "rojo": <SCRIPT TYPE="text/javascript">
alert ("Stop"); // Declaración de variable
break; var mes = "mayo";
case "ámbar": // Sentencia switch
alert("Precaución"); switch (mes) {
break; case "enero":
case "verde": case "marzo":
alert("Adelante"); case "mayo":
break; case "julio":
default: case "agosto":
alert("¡Este color no es de un semáforo!"); case "octubre":
break; case "diciembre":
} alert(mes + " tiene 31 días");
</SCRIPT> break;
case "abril":
La sentencia break esconde un pequeño secreto: en rea­ case "junio":
lidad es opcional. Si la omitimos, estamos dejando sin delimitar case "septiembre":
el bloque case, por lo que el script se seguiría ejecutando hacia case "noviembre":
abajo hasta que se llegue al final del switch o se encuentre alert(mes + " tiene 30 días");
una sentencia break, aunque eso implique "colarnos" dentro break;
del bloque de otro case. Veam os qué pasa si omitimos los case "febrero":
alert(mes + " tiene 28 o 29 días");
break en el ejemplo del semáforo: break;
<SCRIPT TYPE="text/javascript"> }
// Declaración de variable </SCRIPT>

84 85
Fíjese que los case que no llevan bloque de instrucciones • Expresión actualización: Se utiliza para actualizar el
dan la sensación de estar agrupados, consiguiendo que al entrar valor del contador declarado en la expresión inicial, con
en uno de ellos se llegue hasta la instrucción que hay antes del el fin de hacer falsa la condición en algún momento.
break correspondiente. Es como si dijéramos: si la variable Se puede usar cualquier tipo de expresión, aunque lo
mes es igual a "abril", "junio", "septiembre" o "noviembre", en­ m ás común es hacer uso del operador de increm ento
tonces el mensaje es "tiene 30 días". Por consiguiente, el mensaje (++)•
que obtendremos en el ejemplo será "mayo tiene 31 días".
Veamos un rápido ejemplo para aclarar el funcionamiento
de esta estructura.
4.2. Estructuras de bucle <SCRIPT TYPE="text/javascript">
// Sentencia for
for (var x=l; x<10; x++) {
Estas estructuras ejecutan un conjunto de instrucciones re­ alert(x);
petidamente mientras se cumpla una condición. En el momento }
que deja de cum plirse, el bucle se da por terminado. A cada </SCRIPT>
repetición de un bucle se le denomina iteración.
La mecánica que sigue la ejecución de un bucle f o r es la
siguiente:
Advertencia: Tenga especial cuidado en asegurarse de que en
algún momento la condición dejará de cumplirse o provocará 1. La variable x se declara e inicializa con valor 1 (expresión
un bucle infinito (más conocido como "dejar el ordenador inicial). Esto será nuestro contador.
tostado"). 2. Se comprueba si se cumple la condición (el valor de x
es menor que 10). Si el resultado es f a l s e el bucle se
da por terminado, en otro caso se entra en el bloque de
4.2.1. Sentencia for instrucciones.
3. Se ejecuta el bloque de instrucciones, mostrando en
Este tipo de bucle ejecuta las instrucciones de su bloque
nuestro ejemplo el valor de la variable x cada vez (desde
recorriendo un rango de valores de forma secuencial hasta
que la condición deja de cumplirse (valor falso). Su sintaxis 1 hasta 9).
4. Se incrementa el valor de la variable x en una unidad
es la siguiente:
(expresión actualización) y se vuelve al paso 2 .
<SCRIPT TYPE="text/javascript">
// Sentencia for Tam bién es posible utilizar dos o más contadores dentro
for (expresión inicial; condición; expresión de un bucle f o r mediante el operador coma (,). Veamos un
actualización) ( script que nos muestra la relación, un tanto trivial, entre dos
/ / M i bloque de instrucciones números:
}
</SCRIPT> <SCRIPT TYPE="text/javascript">
// Sentencia for
• Expresión inicial: Se utiliza para inicializar una o varias for (var x=l, y=2; x<=10; x++, y++) {
variables que sirvan a m odo de contadores, aunque alert(x + " es menor que " + y);
puede contener expresiones más complejas. Representa }
el primer valor de todo el rango que se va a utilizar </SCRIPT>
dentro del bucle. Aquí hem os inicializado las dos variables con un valor
• Condición: Evalúa en cada iteración si el valor de una distinto en la expresión inicial e incrementado sus respectivos
variable (normalmente la usada como contador) cumple valores en la expresión de actualización. Para recorrer los va­
la expresión especificada. Si no lo hace (valor falso), lores del 1 al 9, sólo hem os comprobado la variable x dentro
significa que el bucle finaliza. de la condición.

86 87
Hemos mencionado que lo más común es una usar una de 4.2.2. Sentencia do - while
las "variables contador" para establecer cuándo finaliza el bucle,
pero esto no tiene por qué ser necesariamente así: Esta sentencia ejecuta una serie de instrucciones, al menos
< SCRIPT TYPE="text/javas cript"> una vez, hasta que la condición que se evalúa tom a valor
I I Declaración de variable falso.
var seguir = true; La sintaxis es la siguiente:
I I Sentencia for
for (var x=l; seguir; x++) { <SCRIPT TYPE="text/javascript">
alert(x); // Sentencia do-while
if (x >= 9) { do {
seguir = false; // Mi bloque de instrucciones
} } while (condición)
</SCRIPT>
}
</SCRIPT>
Como puede fijarse, no hay una condición para ejecutar por
El resultado de este script es el mismo que vimos al principio primera vez el bloque de instrucciones, así que debe tener esto
de este apartado, pero esta vez estamos comprobando cuándo en cuenta a la hora de decidir cuándo usar este tipo de bucles
finaliza el bucle en base al valor de la variable seguir, que para no encontrarse con resultados inesperados. Vamos con
cambia en el i f anidado dentro del bucle for. Si la variable es un ejemplo de tom a de contacto:
fa1 se,el bucle termina, y en otro caso se continúa ejecutando. <SCRIPT TYPE="text/j avascript">
La condición de parada también se podría haber escrito como: // Declaración de variable
seguir == trueo seguir != false. var x = 1;
// Sentencia do-while
Nota: Si la condición es falsa desde el principio el bloque de do {
alert(x);
instrucciones no se ejecutará nunca. Por ejemplo: f o r ( v a r
x++;
x = 1 0 ; x < 5 ; x + + ). } while (x < 10)
</SCRIPT>
Tal como com entam os acerca de la expresión de actualiza­
ción, se puede utilizar cualquier expresión siem pre y cuando La ejecución de este tipo de estructura sigue estos pasos:
haga cum plir la condición de salida en algún m omento. El 1. Se ejecuta el bloque de instrucciones, m ostrando el
siguiente ejem plo es una variante del prim ero que vimos valor de la variable x (desde 1 hasta 9) y realizando un
(m ostrar los núm eros del 1 al 9). En lugar de increm entar post-increm ento de la m isma para no crear un bucle
en una unidad el contador, vam os a hacer que se haga en 2 infinito.
unidades, de m odo que m ostrará los núm eros im pares entre 2. Se com prueba la condición para determ inar si debe
el 1 y el 9: ejecutarse una nueva iteración del bucle. En caso de no
<SCRIPT TYPE="text/j avascript"> cumplirse (x vale 10 ) se da por finalizado y en otro caso
// Sentencia for se vuelve al paso 1 .
for (var x=l; x<10; x=x+2) {
alert (x); A dvertencia: La expresión inicial ( v a r x = 1) debe escri­
} birse antes de comenzar el bucle y la expresión de actualización
</SCRIPT>
(x++) debe ponerse dentro del bloque de instrucciones.
Como podrá ver, hemos usado una expresión de suma para
definir la forma de actualizar la variable que hace de contador Para acortar el código una pizca, se podría realizar el post-
(x). También lo podríamos haber escrito con el operador abre­ incremento dentro de la función alert, aunque esto puede
viado x+ = 2 . restar claridad a nuestro código.

88
<SCRIPT TYPE="text/j avascript">
// Declaración de variable 4.2.4. Sentencias break y continué
var x = 1;
// Sentencia do-while Estas dos sentencias tendrán utilidad únicamente dentro de
do { los bucles y el switch. Veam os qué hace cada una de ellas.
alert(x++);
) while (x < 10) Break
</SCRIPT>
La sentencia break sirve para finalizar prematuramente un
bucle o, como ya hem os visto, para,delimitar un bloque case
4.2.3. Sentencia while dentro de una sentencia switch. Observem os ahora cómo
Esta última sentencia de bucle ejecuta un bloque de instruc­ influye su uso dentro de un bucle:
ciones repetidamente mientras la condición sea verdadera. A <SCRIPT TYPE="text/javascript">
diferencia de la estructura do-while, aquí se comprueba la // Declaración de variable
condición antes de realizar la primera iteración, por lo que no var x = 1;
// Sentencia while
se ejecuta el bloque una primera vez antes de ello. Su sintaxis
while (x < 10) (
es esta:
if (x == 5) {
<SCRIPT TYPE="text/javascript"> break;
// Sentencia while }
while (condición) { x++;
/ / M i bloque de instrucciones }
) alert("La mano tiene " + x + " dedos.");
</SCRIPT> </SCRIPT>

Su funcionamiento es muy sim ilar al do-whi le, así que lo En este script se interrumpe la repetición del bucle while
explicaremos a través de un ejemplo: cuando la variable x toma el valor 5, de manera que el resto de
instrucciones dentro del bloque son ignoradas y se continúa la
<SCRIPT TYPE="text/javascript">
ejecución por la instrucción que hay a continuación del bucle,
// Declaración de variable
var x = 1; en este caso un alert.
// Sentencia while
while (x < 10) { C ontinué
alert(x) ;
x++; Esta otra sentencia nos permitirá saltar una iteración de
} un bucle, ignorando además todas las instrucciones que hu­
</SCRIPT> bieran por debajo. Tras ese salto, la expresión de actualización
es ejecutada y la condición de salida es comprobada antes de
1. Se comprueba la condición para saber si debe ejecutarse
hacer la iteración correspondiente. Vamos a comprender esto
el bloque de instrucciones. Cuando no se cumpla (el con un ejemplo:
valor de x es 10) se dará por finalizado el bucle.
2. El bloque de instrucciones es ejecutado, mostrando el <SCRIPT TYPE="text/javascript">
valor de la variable x (desde 1 hasta 9) y realizando un // Sentencia for
for (var x=l; x < 10; x++) {
post-incremento de la misma. Seguidamente se vuelve
if (x == 4) (
al paso 1. continué;
También se deben escribir las expresiones de inicialización y }
alert("La plaza de parking " + x + " está libre.");
actualización en las mismas zonas que vimos con el do-whi le
}
para que el bucle funcione correctamente. </SCRIPT>

90
El resultado que conseguimos es que se m uestren los dis­
tintos valores de la variable x desde el 1 hasta el 9 excepto el
4, ya que es el que provoca el salto en el bucle.
Si el código fuese este:
<SCRIPT TYPE="text/javascript"> Funciones
// Sentencia for
for (var x=l; x < 10; x++) {
if (x == 9) {
continué;
}
alert("La plaza de parking " + x + " está libre.");
}
</SCRIPT>

Se nos mostrarían m ensajes diciendo que las plazas de la Es muy común a la hora de programar que nos surja la ne­
1 a la 8 están libres, saltaría a la 9 debido al continué y acto cesidad de ejecutar un conjunto de acciones de forma habitual
seguido saldría del bucle ya que tras actualizar x su valor no o simplemente nos convenga que se ejecuten de forma indepen­
cumpliría la condición. diente para dar mayor claridad al código. Pues bien, la solución a
nuestro problema son las funciones, que se encargan de agrupar
una serie de operaciones dentro de un mismo bloque para eje­
cutarlas cuando y cuantas veces queramos. De esta forma, po­
4.3. Estructuras de manipulación demos tener por ejemplo una función que se encargue siempre
de objetos de sumar dos números, con lo que nos evitaremos repetir esa
operación de suma en distintas partes del código.
En este último apartado verem os que JavaScript también Después de leer este apartado sabrá cómo crear sus pro­
nos ofrece algunas estructuras de control para acceder a las pro­ pias funciones, pero debe saber que también existen muchas
piedades y métodos de un objeto de una forma más cómoda. funciones que ya están definidas en JavaScript y le serán de
m ucha utilidad. A lo largo de los capítulos irem os viendo
Como se le hará difícil comprender su funcionamiento sin
muchas de ellas.
conocer cómo definir un objeto en JavaScript, aplazaremos la
explicación de estas estructuras hasta el capítulo correspon­
diente. De todos modos, para que le vayan resultando fam i­
liares, se trata de las estructuras for-in y with. 5.1. Declaración de funciones
JavaScript tiene la palabra reservada function para poder
identificar las funciones que creemos. Veamos mejor un sencillo
ejemplo para explicar la sintaxis que debemos usar:
<SCRIPT TYPE="text/javascript">
// Declaración de función
function sumar(){
var miSuraa = 9 + 2;
)
</SCRIPT>

Primero tenemos la palabra function (indispensable), des­


pués indicamos el nombre que queremos que tenga la función
(sumar) seguida obligatoriamente de los paréntesis y, final­
92
93
mente, escribimos las acciones que queremos que realice nuestra Las funciones pueden ser declaradas en cualquier parte del
función (realizar una suma simple) encerradas entre llaves ( { } ) script, pero si tenemos varias etiquetas <SCRIPT> en nuestra
formando un bloque. Dentro de este bloque podemos declarar página, deben estar en una anterior a la parte donde se hagan
variables y realizar las operaciones que nos venga en gana. las llamadas. En los siguientes ejemplos verem os formas po­
Para utilizar o llamar a una función que hayamos definido es sibles de definir y llamar correctamente una función:
suficiente con escribir su nombre seguido de los paréntesis. Con <SCRIPT TYPE="text/javascript">
esto conseguimos que se ejecuten las acciones que contenga: // Declaración de función en la misma etiqueta
function sumar (){
<SCRIPT TYPE="text/javascript”> // Mis acciones
// Llamada a la función sumar
}
sumar(); // Llamada a la función de la misma etiqueta
</SCRIPT> sumar();
En cuanto a la nomenclatura de las funciones, se siguen </SCRIPT>
<SCRIPT TYPE="text/javascript">
casi las mismas reglas y restricciones que en el caso de las // Llamada a la función de la misma etiqueta
variables: sumar();
I I Declaración de función en la misma etiqueta
1. Nombre en minúsculas, excepto la primera letra de cada
function sumar()(
palabra siguiente a la primera. Esto es una recomenda­ // Mis acciones
ción que le hago, no es en absoluto obligatorio. }
2. Se pueden utilizar caracteres alfanum éricos y algunos </SCRIPT>
símbolos, como el guión bajo o subrayado (_). <SCRIPT TYPE="text/javascript">
3. El nom bre no puede coincidir con el de una palabra I I Declaración de función en otra etiqueta
reservada, como function, ni con el de otro elemento function sumar(){
// Mis acciones
que hayamos definido.
}
Aunque pueda parecer que variables y funciones no se van a </SCRIPT>
diferenciar a simple vista, las funciones se pueden identificar rá­ <SCRIPT TYPE="text/javascript">
I I Llamada a la función de otra etiqueta anterior
pidamente por el uso de los paréntesis. También podemos hacer
sumar();
aún mayor esta diferencia si al declarar funciones utilizamos </SCRIPT>
nombres que representen acciones: sumar mejor que suma o
sumarTresNumeros en vez de sumaTresNumeros. Ahora veremos un ejemplo en el que la definición y la lla­
mada se hacen de forma incorrecta, haciendo que se llame a
Nota.- Una vez más, tenga especial cuidado con el uso de una función que para JavaScript no está definida:
mayúsculas y minúsculas, pues las llamadas a funciones como <SCRIPT TYPE="text/javascript">
S u m ar o SUMAR no son lo mismo. I I Llamada a la función de otra etiqueta posterior (error)
sumar();
</SCRIPT>
<SCRIPT TYPE="text/javascript">
<SCRIPT TYPE=”text/javascript"»
// Declaración de función con nombre corto
// Declaración de función en otra etiqueta
function sumar (){ function sumar(){
// Mis acciones // Mis acciones
) )
// Declaración de función con nombre largo
</SCRIPT>
function sumarTresNumeros(){
// Mis acciones Dentro del bloque de una función (lo encerrado entre llaves)
} se pueden definir y usar variables de todo tipo e incluso llamar
</SCRIPT> a otras funciones.

94
<SCRIPT TYPE="text/j avascript"> Para pasar un parám etro a una función debemos colocar
// Declaración de función un valor entre los paréntesis que se usa en las llamadas a fun­
function sumar(){ ciones. Al hacer esto, el parámetro se inicializa con dicho valor.
// Mis acciones Vamos con un ejemplo de todo esto:
}
// Uso de variables y otra función ya definida <SCRIPT TYPE="text/j avascript">
function miFuncion()( // Declaración de variable
var numerol = 5; var cinco = 5;
var nombre = "Pepe"; // Declaración de función con un parámetro
var otroNumero = numerol; function sumar(numero){
sumar () ; var miSuma = numero + 2;
} }
</SCRIPT> // Llamada a la función con un dato
sumar(3); // El resultado seria 5 ( 3 + 2 )
Truco: Para evitar errores en las llamadas a funciones es // Llamada a la función con una variable
recomendable declarar todas al principio de nuestra página sumar(cinco); // El resultado seria 7 ( 5 + 2 )
dentro de <HEAD>, bien una a una o todas de golpe a través </SCRIPT>
de un fichero externo (.js).
Advertencia: El nombre de nuestros parámetros no puede
coincidir con el de ninguna de las variables declaradas dentro
5.2. Parámetros de la función.

Ahora que ya sabemos definir nuestras propias funciones, Hay que resaltar que los parámetros de las funciones se
vamos a dar un paso más. Como habrá podido observar, la uti­ pasan por valor, es decir, aunque usemos un parámetro dentro
lidad de nuestras funciones hasta ahora no es que sea muy alta de la función para almacenar otro resultado, el valor de la
ya que las acciones que se realizan dentro usan variables con va­ variable original usada en la llamada no varía. Procedam os a
lores fijos que no podemos variar al hacer la llamada (nos puede ver esto con un ejemplo:
interesar sumar números distintos en diferentes llamadas a la
función sumar). Gracias a los parámetros le podremos indicar <SCRIPT TYPE="text/javascript">
a una función los valores con los que queremos operar. A esto // Declaración de variable
var cinco = 5;
se le conoce como pasar o mandar parámetros.
// Declaración de función con un parámetro
function sumar(numero){
5.2.1. Definición de parámetros // Modificamos el parámetro
numero = 4;
Para definir los parámetros de una función basta con poner // El resultado de la suma será 6
el nombre que le identificará, dentro de los paréntesis que var miSuma = numero + 2;
usamos al definir una función. Los parámetros pueden inter­ }
// Llamada a la función con una variable
pretarse como variables dentro de las funciones, pero no es sumar(cinco); // El resultado sería 6 ( 4 + 2 )
necesario declararlas previamente ya que el hecho de que sea // Otra llamada (cinco sigue valiendo 5)
un parámetro implica su declaración. sumar(cinco); // El resultado sería 6 ( 4 + 2 )
</SCRIPT>
<SCRIPT TYPE="text/j avascript">
// Declaración de función con un parámetro Ahora ya podemos decirle a nuestra función qué número
function sumar(numero){ queremos sumar con el 2. Esto está bien pero, ¿y si queremos
var miSuma = numero + 2;
decirle a la función que sume nuestro número con otro que no
}
</SCRIPT> sea el 2? La solución, a continuación.

96 97
5.2.2. Múltiples parámetros Debo señalar que com o las variables o parám etros en
JavaScript no tienen un tipo definido, es posible pasar un
Por suerte, JavaScript ha pensado en todo y nos permite de­ dato de un tipo que no se espera dentro de la función. Por
finir en mía función tantos parámetros como necesitemos sim­ ejemplo, podemos pasar una cadena como parámetro de la
plemente con separar cada nombre con una coma (,). Asimismo, función sumar sin problem as aunque el resultado no sería el
la llamada y paso de parámetros a la función debe hacerse de deseado.
forma análoga. Veamos un ejemplo, extensión del anterior: <SCRIPT TYPE="text/javascript">
<SCRIPT TYPE="text/javascript"> // Declaración de función con dos parámetros
// Declaración de variables function sumar(numerol, numero2){
var cinco = 5, diez = 10; var miSuma = numerol + numero2;
// Declaración de constante }
var MAXIMO = 25; // Llamada a la función con tipo no esperado
// Declaración de función con dos parámetros sumar("salu", 2); // El resultado sería la cadena
function sumar(numerol, numero2){ // "salu2"
var miSuma = numerol + numero2; </SCRIPT>
}
// Declaración de función con tres parámetros
function sumarTresNumeros(numl, num2, num3)( 5.2.3. Parámetros obligatorios y opcionales
var miSuma = numl + num2 + num3;
} Para terminar con este punto, me gustaría ponerle al tanto
// Llamadas a la función con dos valores de que es posible hacer funcionar los parámetros como obliga­
sumar(3, 6); // El resultado sería 9 torios u opcionales. Esto es, si tenemos declarada una función
sumar(cinco, diez); // El resultado sería 15
con dos parámetros podemos prepararla para que no ejecute su
// Llamada a la función con tres valores
sumarTresNumeros(MAXIMO, 3, diez); // El resultado
bloque si no se le han pasado todos los parámetros (los hacemos
// sería 38 obligatorios) o que lo ejecute tanto con dos parámetros, uno
sumarTresNumeros(0, diez, cinco); / / E l resultado o incluso ninguno (los hacem os opcionales) pudiendo hasta
// sería 15 asignarles valores por defecto.
</SCRIPT> Desgraciadamente, y siento dejarle con la miel en los labios,
La llam ada a una función con parám etros debe hacerse a estas alturas del libro no es posible explicarle esta funciona­
lidad ya que se requiere el manejo de objetos (concretamente el
pasando tantos datos como parám etros tenga.
Si se diese el caso de omitir alguno de los parámetros en objeto arguments), los cuales no hemos aprendido a manejar,
la llamada a una función, éstos se inicializarán con un valor pero prometo hacerlo más adelante. De m omento, puedo de­
indefinido (undefined) y el resultado de las acciones será jarle unos ejemplos de cómo se haría este control, omitiendo
el código correspondiente a los objetos:
impredecible.
<SCRIPT TYPE="text/javascript"> <SCRIPT TYPE="text/javascript">
// Declaración de función con dos parámetros // Declaración de función con dos parámetros
function sumar(numerol, numero2){ // obligatorios
var miSuma = numerol + numero2; function sumar(numerol, numero2){
// Hacemos obligatorios los parámetros
} if (no hemos recibido numero 1 &&
// Llamada a la función con un solo valor (error)
no hemos recibido numero2){
sumar(7);
// No hago nada
</SCRIPT>
)else{
En este script, el parám etro numero2 tomará el valor un- var miSuma = numerol + numero2;
def ined, haciendo que el resultado de la suma (7 + unde­ }
}
fined) sea NaN.

98 99
// Asignamos un valor por defecto
// Llamadas a la función
sumar(2, 5); // El resultado seria 7 if (no hemos recibido numero2){
sumar(2); // La función no haría nada numero2 = 7;
sumar(); // La función no haría nada )
var miSuma = numerol + numero2;
</SCRIPT>
< SCRIPT TYPE="text/javascript"> )
// Declaración de función con un parámetro opcional </SCRIPT>
function s u m a r (numerol, numero2){
// Asignamos un valor por defecto
No podrem os hacer que el parám etro numerol sea op­
if (no hemos recibido numero2)( cional y numero2 necesario, ya que la llam ada sumar (,3)
numero2 = 7; provocaría un error. En cambio, numerol puede ser necesario
} y numero2 opcional puesto que la llamada sumar (3) es com­
var miSuma = numerol + numero2; pletamente válida.
}
// Llamadas a la función
sumar(2, 5); // El resultado sería 7
sumar(2); // El resultado sería 9 (usando valor por 5.3. Valores de retorno
// defecto)
sumar(); // El resultado sería NaN (numerol es
// necesario) Las funciones nos proporcionan una funcionalidad más:
</SCRIPT> la posibilidad de devolvernos un valor como resultado de
<SCRIPT TYPE="text/javascript"> las acciones ejecutadas en su bloque. Para ello se utiliza la
// Declaración de función con dos parámetros palabra reservada r e t u r n junto con el valor que queremos
// opcionales devolver.
function sumar(numerol, numero2){
Para recoger el valor devuelto por la función hay que es­
// Asignamos varios valores por defecto
if (no hemos recibido numerol){ cribir una asignación haciendo que el operando de la derecha
numerol= 7; sea una llamada a una función.
Completemos un ejemplo anterior de la función sum ar, ha­
if (no hemos recibido numero2)( ciendo que nos devuelva el resultado de la suma y recogiendo
numero2= 1; su valor en una variable:
var miSuma = numerol + numero2; <SCRIPT TYPE="text/j avascript">
// Declaración de variables
}
// Llamadas a la función var cinco = 5;
sumar(2, 5); // El resultado sería 7 (ningún valor var resultado;
// por defecto) // Declaración de función
sumar(2); / / E l resultado sería 3 (usando valor por function sumar(numerol, numero2){
// defecto) return numerol + numero2;
sumar(); // El resultado sería 8 (usando valores por }
// defecto) // Recogida de valores
</SCRIPT> resultado = sumar(3, 6);
alert(resultado); // Mostrará 9
Cuando los parámetros son opcionales, sólo pueden serlo resultado = sumar(cinco, 10);
aquellos situados a la derecha del último parámetro que sea alert(resultado); // Mostrará 15
necesario para realizar las acciones del bloque. Me explico, bi </SCRIPT>
tenemos la siguiente función:
En el momento en que se devuelve el valor la función ter­
<SCRIPT TYPE="text/j avascript"> minará su ejecución (se sale de la función), ignorando todo el
// Declaración de función con un parámetro opcional
código que hubiese por debajo.
function s u m a r (numerol, numero2){

101
100
<SCRIPT TYPE="text/j avascript"> <SCRIPT TYPE="text/javascript">
// Declaración de variables // Declaración de variable
var cinco = 5; var resultado;
var resultado; // Declaración de función
// Declaración de función function n o D evolverValor(){
function sumar(numerol, n u m ero2){ return;
return numerol + numero2; )
a l e r t ("¡Estoy en la función!"); // Llamada a la función
resultado = noD e v o l v e r V a l o r ();
)
// Llamadas a la función alert(resultado);
resultado = s u m a r (3, 6) ; </SCRIPT>
alert(resultado); // Mostrará 9
Si ejecutamos este script veremos que resultado tiene un
</SCRIPT>
valor unde fined puesto que no se le ha asignado ningún valor
En este ejem plo iónicamente verem os el m ensaje con el con la llamada a la función noDevolverValor.
valor de la variable resultado dado que el otro m ensaje se
encuentra después del return, así que no se ejecutará por 5.3.1. Múltiples valores de retorno
haber salido de la función.
Tam bién es posible utilizar la sentencia r e t u r n sin ningún A veces, dentro del bloque de una función, nos puede in­
valor haciendo que la función termine sin devolver ningún teresar tener más de un valor posible de retorno, pero única­
resultado. Esto resulta útil cuando queremos evitar ejecutar mente será posible devolver uno de ellos ya que, recordemos,
parte del bloque de instrucciones, por ejemplo, en función del la sentencia return nos finaliza la función. Veamos el caso
valor de los parámetros recibidos. de querer devolver el mayor de dos números.

<SCRIPT TYPE="text/j avascript"> <SCRIPT TYPE="text/javascript">


// Declaración de función // Declaración de variables
function acelerar(velocidad){ var resultado;
if (velocidad <= 120) { // Declaración de función
return; function detectarMayor(numerol, numero2){
if (numerol > n u m e r o 2 ) {
alert(velocidad + "km/h: Ojo con el acelerador!"); return numerol;
}e l s e {
1 return numero2;
// Llamada a la función
a c e l e r a r (100); )
a c e l e r a r (120); )
// Llamadas a la función
a c e l e r a r (130);
resultado = d e t e c t a r M a y o r (3, 6); // resultado vale 6
</SCRIPT>
alert(resultado);
Si analizam os detenidam ente la función acelerar del resultado = detectarMayor(10, 8); // resultado vale 10
ejem plo, vem os que si la velocidad pasada com o parám etro alert(resultado);
</SCRIPT>
es m enor o igual a 120 se ejecuta el return y, por tanto, la
función finaliza sin realizar acción alguna. Sin em bargo, Enestescnpf la variable resultado almacena el m ayor de
en cuanto la velocidad es m ayor a 120 se nos m uestra un los dos números que es devuelto por la función después de
mensaje. realizar la comparación entre ambos.
Al utilizar el return sin un valor para devolver dentro de Por último, debe saber que no es obligatorio recoger el valor
una función, ¿qué pasaría si intentásemos recoger el resultado devuelto por una función, pudiendo hacer que sirva directa­
de la llamada de esa función? No hace falta abrir un debate, lo mente como valor de un parámetro o simplem ente se puede
veremos en un ejemplo: dejar que se pierda.

102 103
<SCRIPT TYPE="text/javascript">
Ejemplos con un script:
// Declaración de variables <SCRIPT TYPE="text/javascript">
var resultado; // Llamadas
// Declaración de función a l e r t ( N u m b e r ("1.95")); // 1.95
function sumar(numerol, n u m e r o 2 ) { alert(Number(true)); // 1
return numerol + numero2; a l e r t (Number("hola")); // NaN
} </SCRIPT>
// Recogida del valor de retorno en variable
resultado = s u m a (3, 5); // resultado vale 8
a l e r t(resultado);
// Recogida del valor de retorno como parámetro
5.4.2. Función String
// directo sin almacenarlo
a l e r t ( s u m a r (3, 5 ) ); Esta función permite convertir cualquier valor en una ca­
// Pérdida del valor de retorno dena. Aquí siempre es posible la conversión por lo que el valor
s u m a r (3, 5); devuelto es una cadena en todos los casos.
</SCRIPT>

Tabla 5.2. Ejemplos con la función String.

5.4. Funciones predefinidas Valor Conversión

JavaScript incluye una serie de funciones ya definidas que 5 "5"


pueden ser usadas con cualquier variable, valor directo u ob­ -3 "-3"
jeto. Gracias a muchas de estas funciones podrem os realizar 1.95 "1.95"
una conversión explícita de tipos de datos. "1,95” "1,95"
true "true"
5.4.1. Función Number false "false"
"hola" "hola"
Esta función permite expresar cualquier valor como un nú­
mero. En caso de que la conversión no sea posible, se devuelve NaN "NaN"
el valor NaN (Not a Number).
Ejemplos con un script:
Tabla 5.1. Ejemplos con la función Number. <SCRIPT TYPE="text/javascript">
I I Llamadas
I Valor Conversión I alert(String(1.95)); // "1.95"
alert(String(true)); I I "true"
5 5 alert(String("hola")); I I "hola"
</SCRIPT>
-3 -3
1.95 1.95
"1.95" 1.95 5.4.3. Función isNaN
"1,95" NaN
Esta función comprueba si un valor no es un número, por
true 1 lo que devolverá false en caso de ser un núm ero y true en
false 0 cualquier otro caso. Antes de comprobar el valor, se aplica
"hola" NaN automáticamente la conversión implícita de tipos.

105
104
Tabla 5.3. Ejemplos con la función isNaN. Ejemplos con un script:

Valor Resultado <SCRIPT TYPE="text/javascript">


// Llamadas
5 false alert(isFinite(1.95)); // true
alert(isFinite(true)); // true
-3 false alert(isFinite("hola")); // false
1.95 false </ SCRIPT>
"1.95" false
"1,95” true
5.4.5. Función parselnt
true false
false false Esta función permite transformar cualquier cadena en un
"hola" true número entero, siguiendo estas reglas:
NaN true
1. Si la cadena contiene varios núm eros separados, sólo se
convierte el primero.
Ejemplos con un script:
2. Los espacios al principio y final de la cadena son omi-
<SCRIPT TYPE="text/javascript"> tidós, pero se tienen en cuenta los espacios intermedios,
// Llamadas que actuarán como separadores de números.
a l e r t ( i s N a N (1.95)); // false
3. Si el primer carácter de la cadena o la cadena completa
alert(isNaN(true)); // false
alert(isNaN("hola")) ; // true no se puede convertir, se devuelve NaN.
</SCRIPT>
Nota: Si intenta convertir un nútnero con decimales, éstos
5.4.4. Función isFinite se omitirán ya que la función sólo convierte el valor a un
entero.
Esta función comprueba si un valor es un número finito. Si
el valor es NaN, Inf inity o -Inf inity se devolverá false
y en el resto de los casos se devolverá true. También se realiza Tabla 5.5. Ejemplos con la función parselnt.
la conversión implícita de tipos antes de comprobar el valor.
Valor Conversión
Tabla 5.4. Ejemplos con la fundón isFinite.
"5” 5
Valor Resultado "-3" -3
5 true "1.95" 1
1.95 true "1,95" NaN (no convertible)
"1.95" true “true" NaN (no convertible)
"1,95" false (NaN tras conversión implícita) "false" NaN (no convertible)
true true "hola" NaN (no convertible)
false true "1 2 3" 1
"hola" false (NaN tras conversión implícita)
" 1.5 2 3" 1
NaN false
"1 b 3" 1
Infinity false
"a 2 3" NaN (primer carácter no convertible)
-Infinity false

106 107
Ejemplos con un script: 5.4.6. Función parseFloat
<SCRIPT TYPE=" text/javascript">
Perm ite convertir cualquier cadena en un núm ero real,
// llamadas
mediante las mismas reglas que sigue p a r s e l n t con un pará­
alert(parselnt("1.95")); // 1
alert(parselnt("true")); // NaN metro (no hay segundo parámetro opcional en esta función).
alert(parselnt ("1 b 3")); // 1
</SCRIPT> Nota: El separador decimal en JavaScript es el punto (.).
Esta función cuenta además con un segundo parámetro op­
cional para indicar la base (entre 2 y 36) en la que se encuentra Tabla 5.7. Ejemplos con la función parseFloat.
el valor de la cadena a convertir. El resultado de la conversión Valor Conversión
siempre estará expresado en base 10.
Si no se especifica este parám etro se siguen los siguientes "5" 5
criterios: "-3" -3
"1.95" 1.95
1. Si la cadena empieza por "Ox", la base es 16.
2. Si la cadena empieza por "0", la base es 8 (en desuso). "1,95" NaN (no convertible)
3. Para el resto de valores, la base es 10. "true" NaN (no convertible)
"false" NaN (no convertible)
Tabla 5.6. Ejemplos con la función parselnt especificando "hola" NaN (no convertible)
una base. "1 2.5 3" 1
Conversión en base 10 " 1 2 3" 1
Valor Base
"1.5 b 3" 1.5
"9" 10 9 (decimal) "a 2 3" NaN (primer carácter no convertible)
n-j -j ii 8 9 (octal)
"1 A" 16 26 (hexadecimal) Ejemplos con un script:
”011" 2 3 (binario) <SCRIPT TYPE="text/javascript">
// Llamadas
"9" - 9 (se asume base 10) a lert(parseFloat("1.95")); // 1.95
"011" - 9 (se asume base 8) alert(parseFloat("true")); // NaN
a lert(parseFloat("1.5 b 3")); // 1.5
"0x1 A" - 26 (se asume base 16)
</SCRIPT>
"0x1 A" 10 NaN (no convertible en base 10)
"OxHola" 16 NaN (no convertible) 5.4.7. Función escape

Ejemplos con un script: Esta función se encarga de codificar los caracteres especiales
(espacio, acentos, signos de puntuación...) de una cadena, de­
<SCRIPT TYPE=" text /javas cript "> volviéndola en formato UNICODE ( h t t p : / / u n ic o d e . org ).
// Llamadas
Cada carácter codificado irá con la forma %xx, siendo x x su
alert(parselnt("9", 10)); // 9
equivalente hexadecimal. Esta función es útil para que una ca­
alert(parselnt("lñ", 16)); // 26
alert(parselnt("9")); // 9 dena pueda ser leída sin problem as, especialmente cuando se
alert(parselnt("Oxlñ")); // 26 trata de transacciones HTTP (envíos de formularios, cookies...)
alert(parselnt("OxHola", 16)); // NaN donde el espacio en blanco, por ejemplo, no puede transmitirse
</SCRIPT> sin codificar ya que provocaría un error.

108 109
Tabla 5.8. Ejemplos con la función escape. Tabla 5.9. Ejemplos con la función unescape.

Valor Codificación | Valor Descodificación

"dos palabras" "dos%20palabras" "dos%20palabras" "dos palabras"


"¿hola?" "%BFhola%3F" "%BFhola%3F" "¿hola?"
"¡Mi código!" "%A1 Mi%20c%F3digo%21" "%A1 Mi%20c%F3digo%21" "¡Mi código!"

Ejemplos con un script: Ejemplos con un script:


<SCRIPT TYPE="text/javascript"> <SCRIPT TYPE="text/j avascript">
// Llamadas / / Llamadas
alert(escape("dos palabras")); // "dos%20palabras" alert(unescape("dos%20palabras")); // "dos palabras"
alert(escape("¿hola?")); // "%BFhola%3F" alert(unescape("%BFhola%3F")); // "¿hola?"
alert(escape(” ¡Mi código!")); // "%AlMi%20c%F3digo%21" alert(unescape("%AlMi%20c%F3digo%21")); // "¡Mi código!"
</SCRIPT> </SCRIPT>

Sí, es difícil descifrar a simple vista qué es lo que habíamos Al igual que ocurre con la función escape, está recom en­
escrito antes de codificar algunos de los caracteres. Pero mien­ dado el uso de las funciones decodeURI o decodeURICom-
tras JavaScript lo entienda no tiene por qué sufrir. ponent.
La función e s c a p e no codifica los siguientes caracteres
especiales, por lo que los deja tal cual están:
5.4.9. Función eval
1. Asterisco (*)
2. Arroba (@) Esta función, de gran utilidad en muchos casos, interpreta
3. Signo de resta (-) una cadena y la ejecuta como si se tratase de una porción de
4. Guión bajo o subrayado (_) código JavaScript.
5. Signo de suma (+) En caso de que haya más de una instrucción en la cadena,
6. Punto ( . ) separadas por punto y coma ( ;) , eval ejecuta cada una de ellas
7. Barra o slash (/) por separado y en el orden que aparecen escritas.
Dado que los caracteres especiales son m uy usados en
el paso de parám etros entre páginas W eb (formularios, por Tabla 5.10. Ejemplos con la función eval.
ejemplo), está recomendado el uso de las funciones encodeU RI
o encod eU R IC om pon en t en su lugar ya que funcionan de Valor Resultado
forma muy similar. Además, como e s c a p e no trabaja apro­
"2+2" 4 (devuelve la suma).
piadamente con caracteres fuera del código ASCII ( h t t p : / /
www , a s c i i . c l / e s / ) s e recomienda usar esas funciones al­ ”suma(2, 2);" 4 (devuelve la ejecución de la
ternativas desde JavaScript 1.5 en adelante. función, que debe existir).
"var num=3; suma(2, num);" 5 (declara la variable y devuelve
la ejecución de la función).
5.4.8. Función unescape
"suma(2, num);" Error (num no está definida).
Com o puede im aginar, esta función realiza el proceso "suma(2, num); var num=3;" Error (num se define después).
inverso a la que acabamos de ver: descodifica los caracteres "hola" Error (interpreta hola como una
convertidos con la función e s c a p e , volviéndolos a dejar como
variable).
estaban.

110 111
// Uso de variable local
Ejemplos con un script:
alert(vale); // Error, variable no definida
<SCRIPT TYPE="text/javascript"> </SCRIPT>
// Llamadas
alert(eval("2+2")); // 4 En este ejemplo com probamos cómo el valor de la variable
alert(eval("var num=3; sumar(2, num);")); 1 / 5 local v a l e es correcto sólo si es utilizado dentro de la propia
alert(eval("hola")); I I Error función, que es la única que tiene acceso a ella, mientras que
</SCRIPT> si intentamos obtener su valor directamente obtendremos un
error al no estar definida fuera de la función.
Nota: Use la función e v a l sólo si está manejando cadenas.
También es capaz de interpretar código JavaScript, pero estará Nota: Los parámetros de una función son variables locales
haciendo un uso indebido. Por ejemplo: e v a l (2 + 2 ) ; o de la misma.
e v a l (s u m a r ( 2 , 2 ) ) ;
Por otro lado, las variables definidas dentro de otro tipo de
bloques (estructuras de control) tienen un comportamiento un
5.5. Ámbito o alcance de las variables tanto peculiar puesto que no son locales en el sentido estricto
de la palabra. La variable estará definida en todo momento,
por lo que es accesible desde fuera del bloque, pero pueden
Se le llama ámbito o alcance de una variable al lugar donde
ocurrir dos cosas al intentar leer su valor:
está disponible después de haber sido declarada, cosa que
ocurre en todos los lenguajes de programación. En el caso de 1. Si el bloque es ejecutado (se cumple su condición de
JavaScript, dado que se declaran las variables dentro de una entrada), entonces el valor que se asigne a la variable
página Web, su disponibilidad queda reducida a dicha página, estará igualmente disponible fuera de él.
no pudiendo acceder a las de otra página. 2. Si no se ejecuta nunca el bloque (la condición no se
Dentro de una página hay dos tipos de ámbitos: local y cumple la primera vez), la variable es accesible pero con
global. un valor u n d e f in e d .
<SCRIPT TYPE="text/javascript">
// Estructura con una variable local
5.5.1. Ámbito local if (5 < 25) {
var vale = true;
Si declaramos una variable en el bloque de una función e }
intentamos usarla fuera de ella, obtendremos un error ya que // üso de variable local
es como si nunca hubiera sido declarada. alert(vale); // true
</SCRIPT>
<SCRIPT TYPE="text /javascript ">
I I Declaración de una función con una variable local En este prim er ejemplo, la variable v a l e es declarada de
function validar(numero)( forma local dentro del bloque i f . Como la condición de en­
var vale; trada se cumple (5 < 25) entonces su valor es accesible fuera
if (numero < 25) {
vale = true;
del bloque. Veamos el caso contrario.
)else{ <SCRIPT TYPE="text/javascript">
vale = false; // Estructura con una variable local
} if (30 < 25) {
return vale; var vale = true;
} }
I I Llamadas a función // Uso de variable local
alert(validar(5)); // true alert(vale); // undefined
alert(validar(30)); // false </SCRIPT>

113
En esta otra ocasión, como la condición de entrada no se De este m odo conseguimos lo siguiente:
cumple (30 < 2 5 ) hará que la variable local v a l e no tome el
1. La constante global MAXIMO es accesible dentro de la
valor t r u e . Entonces, puesto que la variable sí está definida
función y la comparación con el parámetro num ero se
para JavaScript, nos encontramos con un ejemplo con un valor
hace de forma correcta.
no definido.
2. El valor de la variable local vale de la función validar
Para evitar este tipo de situaciones "extrañas", intentaremos
es recogido correctamente en las llamadas a la misma.
declarar previamente todas las variables que se usen dentro de
3. Al intentar acceder directamente al valor de vale fuera
una estructura de control y, siempre que sea posible, asignarle
de la función validar, obtenemos un error ya que es
un valor inicial por defecto.
de ámbito local y, por tanto, sólo accesible dentro de la
<SCRIPT TYPE="text/javascript"> función.
// Declaración de variable con valor inicial 4. El valor de la constante MAXIMO tam bién puede ser
var vale = false; mostrado si la utilizamos en otra parte del código.
// üso de variable en estructura
if (30 < 25) ( En el apartado anterior comentábamos las situaciones "ex­
vale = true; trañas" que se pueden crear al declarar una variable local dentro
) de una estructura de control y la forma de evitarlas:
// Uso de variable
alert(vale); // false <SCRIPT TYPE="text/j avas cript">
</SCRIPT> // Declaración de variable con valor inicial
var vale = false;
// üso de variable en estructura
5.5.2. Ámbito global if (30 < 25){
vale = true;
Cuando la variable está definida fuera de un bloque, la )
// üso de variable
hacemos accesible desde cualquier parte del código, incluso
alert(vale); // false
dentro de las funciones y estructuras de control. </SCRIPT>
Veamos un ejemplo con variables tanto locales como glo­
bales para que el concepto de ámbito quede más claro: Si miramos de nuevo el código y lo juntam os con el con­
cepto de ámbito recién explicado, nos podremos dar cuenta
<SCRIPT TYPE="text/javascript">
// Declaración de variable global
de que lo que hicim os en realidad fue darle un ámbito global
var MAXIMO = 25; a la variable vale.
// Declaración de una función con una variable local
function validar(numero){
var vale; 5.5.3. Prioridad de las variables
if (numero < MAXIMO){
vale = true; Si dentro de una función se declara una variable local con
}else{ el mismo nombre que una variable global, tiene preferencia la
vale = false; local a la hora de ser utilizada dentro de esa función. Veamos
} algunos ejemplos:
return vale;
<SCRIPT TYPE="text/javascript">
}
// Oso de variables de distintos ámbitos // Declaración de variable global
alert(validar(5)); // true var numero = 5;
alert(validar(30)); // false // Declaración de una función con una variable local
alert(vale); // Error, variable no definida function darNumero(){
alert(MAXIMO); // 25 var numero = 10;
</SCRIPT> return numero;

114 115
}
// Oso de variables con mismo nombre
alert (numero + ”\n” + darNumeroO + "\n" + numero);
</SCRIPT>

[Aplicación JavaScript] B

5
| Aceptar!

Figura 5.1. Ejemplo 1 de prioridad de variables.

Si observa la figura 5.1 verá que el resultado de nuestro


ejemplo cumple la regla de prioridad: la llamada a la función
d a r Numero no altera el valor de la variable global (5) ya que
usa la local con el mismo nombre.
Aunque ya tenemos la buena costumbre de declarar nues­
tras variables siempre con la sentencia v a r , tenga presente que
el omitirla al declarar la variable local del ejemplo anterior hará
que sí se modifique la variable global.
<SCRIPT TYPE="text/javascript">
I I Declaración de variable global
var numero = 5;
// Declaración de una función sin una variable local
function darNumeroO {
numero = 10;
return numero;
}
// Oso de variables con mismo nombre
alert (numero + ”\n" + darNumeroO + "\n" + numero);
</SCRIPT>

[Aplicación JavaScript]

¿h %
10

| Aceptar |

Figura 5.2. Ejemplo 2 de prioridad de variables.

La pequeña diferencia respecto al código anterior (omisión


de la sentencia v a r ) provoca que no declaremos ninguna va­
riable local en la función, así que se utiliza la variable numero
de ámbito global a la hora de asignar el valor 10.

116
6
Programación orientada
a objetos

La program ación estructurada (la que hemos visto hasta


ahora) tiene los datos y las funciones separados sin una rela­
ción entre ellos, ya que lo único que se busca es procesar una
serie de datos para obtener un resultado. Básicamente se podría
decir que sólo se escriben funciones que procesan datos, dado
que con esta forma de program ar se tiende a pensar primero
en la forma de funcionar de los procedim ientos o funciones,
dejando en un segundo plano las estructuras de datos que se
manejan dentro de esas funciones.
La program ación orientada a objetos (POO) introduce
una nueva estructura (los objetos) que contiene los datos y
las funciones que manejan éstos, estando así ambas partes
relacionadas. Esto hace más fácil equiparar los objetos a cómo
son las cosas en la vida real ya que cualquier cosa o entidad
se compone de distintas piezas o partes y form an un todo.
Haciendo un símil, se diría que las piezas (objetos) tienen sus
propias características (datos y funciones) y al juntarse con
otras (escribir un código) crean un elemento con una utilidad
determinada (el programa o script).
Los datos que contiene un objeto son conocidos como pro­
piedades o atributos, y las funciones como métodos.
Si hacemos memoria del apartado 2.2.4 del capítulo 2, recor­
daremos que se explicó un ejemplo de objeto con un coche. Las
propiedades de ese objeto serían su conjunto de características
(color, marca y modelo) y los m étodos las distintas funciona­
lidades que ofrece el coche (arrancar, acelerar y frenar).
Cada objeto puede diferenciarse de otro por su estructura
(el objeto coche no se parece al objeto mesa) o simplemente por
los valores de sus propiedades. Siguiendo con el ejemplo, no
todos los coches son iguales en sus características (color rojo,

117
azul, v erd e...) pero todos sí ofrecen las m ismas funcionali­ en el ejemplo del constructor mediante llaves, ya que realmente
dades (se entiende que hablamos de funcionalidades básicas, se crea una instancia, mientras que function nos deja una
no vamos a adentram os en el equipamiento extra). Con esta estructura lista para crear instancias.
observación aparece otro concepto importante: las instancias. En las secciones que siguen verem os cómo usar cada tipo
Todas parten de la misma estructura base pero sus propiedades de constructor.
toman distintos valores.

6.2. Trabajar con objetos


6.1. Definición de un objeto (constructor)
Antes de m eternos más en faena con los objetos, voy a
Cualquier lenguaje de program ación actual nos permitirá presentarle los distintos operadores y sentencias que tiene
crear y definir nuestros propios objetos para poder adaptar el JavaScript para poder acceder a los distintos elementos que
código a nuestras necesidades. Además cada lenguaje ofrece constituyen los objetos.
una colección más o menos amplia de objetos predefinidos • El punto ( . ): sirve para obtener el valor de una pro­
que podremos usar igualm ente sin necesidad de quebrarnos piedad o ejecutar un método del objeto que le precede.
la cabeza inventándolos por nuestra cuenta. Se utiliza como sigue:
Una vez que tenem os claro las propiedades y métodos
que van a form ar nuestro objeto, definiremos su constructor, var color = miCoche.color;
miCoche.arrancar();
cuyo objetivo es crear e inicializar las instancias que hagamos
de él. Para conseguir esto disponem os de dos opciones en • Los corchetes ( [ ] ): sirven para lo mismo que el punto,
JavaScript: pero para acceder a una propiedad o método debemos
escribirlo como un string.
1. Utilizar llaves ( { } ), dentro de las cuales definiremos todas
las propiedades y métodos. La sintaxis sería esta: var color = miCoche["color"];
miCoche["arrancar"] ();
var miObjeto = {propiedades, métodos};
• new : este operador nos permite crear una instancia del
En realidad esto no es un constructor en el sentido objeto que indiquemos.
estricto de la palabra puesto que no podrem os crear
instancias a partir de esta estructura, sino que estaríamos var miCoche = new Coche();
creando una instancia directamente. De modo que po­ • delete: se utiliza para borrar una propiedad de una
dríamos decir que actúan como un constructor "de un instancia, dejando de estar accesible. Los métodos no se
solo uso". pueden eliminar de una instancia.
2. U tilizar la sentencia function, definiendo dentro
delete miCoche.color;
de ella las propiedades y métodos. Se escribiría de la
siguiente manera: • in: nos permite saber si una propiedad existe en el obj eto
function MiObjeto() { que indiquemos, devolviendo un valor true si existe,
// Definición de propiedades y false si no. El nombre de la propiedad debe estar
// Definición de métodos escrito como un string.
> alert("color" in Coche);
Como nom enclatura a seguir, le recom iendo que ponga
• instanceof: nos dice si la instancia especificada co­
en mayúsculas la primera letra de cada palabra, incluida la
rresponde al objeto que indiquemos.
primera. De este modo será más fácil diferenciarlos de las fun­
ciones. Fíjese que se ha seguido la nom enclatura de variables alert(miCoche instanceof Coche);

118 119
• this: este operador sirve para referirse a un objeto function Coche(valorMarca, valorModelo, valorColor) {
como sustituto de su nom bre. Su funcionam iento lo // Definición de propiedades
verem os a continuación para que pueda comprenderlo this.marca = valorMarca;
this.modelo = valorModelo;
totalmente.
this.color = valorColor;
}
I I Definimos instancias
6.2.1. Definición de propiedades en un objeto var miCochel = new Coche("Fiat", "Punto", "Rojo");
var miCoche2 = new Coche("Honda", "Civic", "Azul");
Según el tipo de constructor que hayamos empleado, las var miCoche3 = new Coche("Seat” , "Ibiza", "Negro");
propiedades se definen de una manera u otra. Aquí veremos
el procedimiento a seguir para cada uno de ellos. No habría ningún problema en caso de que los parám e­
En el caso de haber usado las llaves, las propiedades se es­ tros tengan el mismo nombre que las propiedades, ya que la
criben como pares de la forma propiedad:valor y separando sentencia this ayuda a diferenciar cuándo nos referimos a la
cada uno de esos pares con una coma. propiedad propia del objeto y cuándo al parámetro.
function Coche(marca, modelo, color) {
var miCoche = {marca: "Fiat", modelo: "Punto", color:
// Definición de propiedades
"Roj o " };
this.marca = marca;
Si por el contrario hemos utilizado la sentencia function, this.modelo = modelo;
entonces debemos hacer uso de la palabra reservada this this.color = color;
para hacer referencia a elementos del propio objeto. La sintaxis }
// Definimos instancias
básica sería esta: var miCoche = new Coche("Fiat", "Punto", "Rojo");
function CocheO { var elCocheDeMiVida = new Coche("Lamborghini",
// Definición de propiedades "Murciélago", "Blanco");
this.marca = "Fiat";
this.modelo = "Punto";
this.color = "Rojo"; 6.2.2. Definición de métodos
1
De igual m odo que las propiedades, tam bién podem os
Esto está bien pero tiene un inconveniente: ¡los valores que definir los métodos que tendrá nuestro objeto y las acciones
se asignan son fijos! Si creásemos instancias del objeto Coche que ejecutará cuando sea llamado. Para esto tenemos dos op­
todas tendrían los mismos datos. En el prim er caso (uso de ciones: definir la función a la vez que el método o asignarle
llaves) sólo podremos solventarlo asignando distintos valores una función ya existente.
a cada instancia que creemos directamente con las llaves, pero
tendremos que repetir una y otra vez todos los nom bres de las D efin ir fun cio n es a la vez que un m étodo
propiedades.
Esto lo haremos con la sentencia function, que ya cono­
var miCochel = (marca: "Fiat", modelo: "Punto", color: cemos, pero sin asignar un nombre de función puesto que lo que
"Rojo");
haremos es almacenar el contenido de dicha función dentro de la
var miCoche2 = {marca: "Honda", modelo: "Civic", color:
propiedad que representa al método. Veámoslo con ejemplos:
"Azul"};
var miCoche3 = {marca: "Seat", modelo: "Ibiza", color: // Objeto definido con llaves
"Negro"}; var miCoche = {arrancar: function() { alert("brummm"); }};
// Objeto definido con function
Sin em bargo, si u tilizam os la sentencia function lo
function CocheO {
tendrem os m ucho más fácil puesto que podrem os usar los // Definición de métodos
parám etros com o los valores que se asignarán a las propie­ this.arrancar = function() { alert("brummm"); };
dades. }

120 121
En am bos casos hem os definido el m étodo arrancar de todo desde el punto de vista del m antenim iento del código,
la m isma form a: asignando una función a la propiedad del ya que es m ás fácil localizar las funciones para hacer alguna
objeto que sim boliza el m étodo. Lo único que cam bia es cómo m odificación.
realizam os esa asignación: con dos puntos ( : ) en un caso y // Definición de función
con el operador de asignación (=) en el otro. Para llam ar a function arrancarCoche(){
cualquiera de los m étodos basta con acceder a él como una alert("brummm");
función, junto con el operador punto ( . ) por estar dentro de )
un objeto: // Asignar función a método
var miCoche = {arrancar: arrancarCoche};
// Método de objeto definido con llaves function CocheO {
miCoche.arrancar(); // Definición de métodos
// Método de objeto definido con function this.arrancar = arrancarCoche;
var miCoche = new Coche(); }
miCoche.arrancar();
M ediante esta técnica, cuando se haga una llamada al m é­
Fíjese que para la segunda llamada es necesario crear pre­ todo arrancar del objeto, en realidad se estará ejecutando
viamente una instancia del objeto para poder acceder a las el código correspondiente a la función arrancarCoche. Las
propiedades y métodos. llamadas a los métodos no varían respecto a lo visto hasta
En el caso de que necesitásem os pasar parám etros a los ahora:
m étodos, tendrem os que declarar nuestros m étodos de una
// Método de objeto definido con llaves
form a casi idéntica a com o lo h aríam os con una función miCoche.arrancar();
normal. // Método de objeto definido con function
var miCoche = new Coche();
// Objeto definido con llaves
miCoche.arrancar();
var miCoche = {acelerar: function(velocidad) {
alert("acelerando hasta " + velocidad); }}; Si necesitam os que nuestra función reciba parámetros tan
// Objeto definido con function sólo habrá que indicarlos cuando definamos la función externa.
function CocheO (
La asignación al método no varía respecto a una función sin
I I Definición de métodos
this.acelerar = function(velocidad) { parámetros, y el método quedará preparado para recibir los
alert("acelerando hasta " + velocidad); }; mismos parámetros:
} I I Definición de función con parámetros
function acelerarCoche(velocidad){
Las llamadas a métodos con parámetros es exactamente
alert("acelerando hasta " + velocidad);
igual que para una función normal.
>
// Método de objeto definido con llaves // Asignar función a método
miCoche.acelerar (100); var miCoche = {acelerar: acelerarCoche};
I I Método de objeto definido con function function CocheO {
var miCoche = new CocheO; I I Definición de métodos
miCoche.acelerar(100); this.acelerar = acelerarCoche;
}
A sig n a r fun cio n es existen tes a un m étodo Veamos cómo serían entonces las llamadas con parámetros:
I I Método de objeto definido con llaves
Este otro sistem a consigue el mismo resultado que el an­
miCoche.acelerar(lOO);
terior, pero únicam ente se diferencia en que las funciones // Método de objeto definido con function
que se asignan a los m étodos ya se encuentran definidas var miCoche = new Coche();
fuera del objeto. Esto puede resultar m ás interesante, sobre miCoche.acelerar(100);

122 123
¡Exactamente igual que con el prim er método! Esto es lo 6.3.1. Sentencia for - in
bueno de la flexibilidad que nos ofrece JavaScript: podemos
definir las cosas de distintas maneras, pero la forma de utili­ Gracias a esta sentencia podremos obtener todas las pro­
zarlas es la misma. piedades y métodos de una instancia de un objeto y también
Una característica que debemos tener en cuenta de los mé­ acceder a sus valores o ejecutarlos. Esto es útil cuando no cono­
todos es que su código podrá acceder a todas las propiedades del cemos sus nombres o queremos recorrer todas de principio a fin.
objeto simplemente con utilizar la sentencia t h i s . Esto se puede La sintaxis que se debe seguir para utilizarla es la siguiente:
hacer con cualquiera de los dos métodos que acabamos de ver: <SCRIPT TYPE="text/javascript">
<SCRIPT TYPE="text/javascript"> // Sentencia for-in
// Definición de función con acceso a propiedades for (nombrePropiedad in instancia) {
function mostrarColorCoche() { I I Mi bloque de instrucciones
alert("El color del coche es: ” + this.color); }
} < / SCRIPT>
I I Definición del objeto
Si usamos esta estructura, el bloque de instrucciones que
function Coche(marca, modelo, color) {
// Definición de propiedades
definamos será ejecutado para cada una de las propiedades.
this.marca = marca; El nombre de la propiedad queda almacenado en una variable
this.modelo = modelo; (nombrePropiedad) que puede ser declarada en el momento
this.color = color; de escribir la sentencia, como ya ocurría en los bucles for. Esta
// Acceso a propiedades desde función definida dentro variable la usaremos dentro del bloque para realizar los accesos
this.mostrarMiColor = function() { alert("Mi color que necesitemos. Si el objeto no tuviese ninguna propiedad
es: " + this.color); };
el bucle no se ejecutaría, pasando directamente a la siguiente
// Acceso a propiedades desde función existente
this.mostrarColor = mostrarColorCoche;
instrucción del script.
} Imaginemos que usamos dentro de esta sentencia una ins­
var miCoche = new Coche("Fiat", "Punto", "Rojo") ; tancia del objeto Coche con las propiedades color, marca y
miCoche.mostrarMiColor(); modelo y el m étodo arrancar:
miCoche.mostrarColor();
</SCRIPT> <SCRIPT TYPE="text/javascript">
// Declaración de la instancia
[Aplicación JavaScript]
var miCoche = new Coche("Fiat", "Punto", "Rojo");
I I Declaración de variable
Mi color os! Rojo
var mensaje = "Contenido de \"miCoche\":\n";
| [Aplicación JavaScript]
IR) // Sentencia for-in
for (var miPropiedad in miCoche) {
j f , El color del coche e s : Rojo
mensaje += "\t* " + miPropiedad + "\n";
¡ Aceptar |
}
// Mostramos las propiedades
alert(mensaje);
Figura 6.1. Acceso a propiedades desde un método. </SCRIPT>

[Aplicación JavaScript]
6.3. Estructuras de manipulación E

i *\ Contenido de "miCoche',:

de objetos t-*.N * marca


* modelo
* color
* arrancar

Como ya adelantamos en el capítulo referente a las estruc­ f Aceptar ^

turas de control, JavaScript nos ofrece algunas estructuras para


acceder a las propiedades y métodos de un objeto. Figura 6.2. Sentencia for-in muestra las propiedades de la instancia.

124 125
Como resultado de ejecutar este script veríamos un mensaje <SCRIPT TYPE="text/javascript">
// Accesos consecutivos a propiedades y métodos
con todos los nombres de las propiedades y métodos de nuestra
alert(miCoche.color);
instancia: color, marca, modelo y arrancar. alert(miCoche.marca);
También sería posible acceder al valor de dichas propiedades alert(miCoche.modelo);
mediante el uso de los corchetes ( [ ]) como operador sobre miCoche.arrancar () ;
objetos. Veamos cómo realizar esto con el ejemplo anterior: </SCRIPT>

<SCRIPT TYPE="text/javascript"> Como ve, para mostrar los valores de estas tres propiedades
// Declaración de la instancia
y llamar al método debemos escribir repetidamente el nombre
var miCoche = new Coche("Fiat", "Punto", "Rojo");
// Declaración de variable
del objeto al que queremos acceder (miCoche). Esto resultará
var mensaje = "Valores en \"miCoche\":\n"; aún más molesto cuantas más operaciones necesitemos hacer
// Sentencia for-in sobre las propiedades o métodos. Sin embargo, gracias a la sen­
for (var miPropiedad in miCoche) { tencia with, podrem os fijar el objeto al que vam os a acceder y
mensaje += "\t* V" + miPropiedad + "V tiene escribir únicamente el nombre de la propiedad o método para
valor: " + miCoche[miPropiedad] + "\n"; acceder a ellos. Veamos primero la sintaxis:
)
// Mostramos las propiedades y valores <SCRIPT TYPE="text/javascript">
alert(mensaje); // Sentencia with
</SCRIPT> with (objeto) {
// Bloque de instrucciones sobre las propiedades
[Aplicación JavaScript] // y métodos
¡ i Valores en "miCoche":
>
\ * 'marca1 tiene valor: Fiat </SCRIPT>
* 'modelo' tiene valor: Punto
* 'color'tiene valor: Rojo
* 'arrancar' tiene valor: function 0 ■{
alert("brurnmm");
A hora usarem os esta nueva estructura con el ejemplo que
> vim os al principio del apartado para que pueda obsevar la
diferencia:
Figura 6.3. Sentencia for-¡n muestra las propiedades <SCRIPT TYPE="text/javascript”>
de la instancia y sus valores. // Sentencia with
with (miCoche) {
alert(color);
Gracias a este código obtendríamos el resultado de la fi­ alert(marca);
gura 6.3. Como curiosidad, puede ver que el "valor" del mé­ alert(modelo);
todo arrancar se muestra en realidad como el código que arrancar () ;
contiene. )
Quizá ha pasado desapercibido, pero dese cuenta de que </SCRIPT>
hemos accedido a todas las propiedades de una instancia sin ¿Ha visto? Ya no es necesario escribir una y otra vez el
saber sus nombres ni cuántas había. Esta es la gran ventaja de nombre de la instancia, lo cual hace más cómodo y limpio el
poder contar con esta estructura de control. acceder tanto a las propiedades como al método. Note que
también se ha eliminado el operador punto ( .) puesto que la
6.3.2. Sentencia with sentencia w i t h hace ese trabajo por nosotros.
Para terminar con esta sentencia, destacar que dentro del
Notará que en algunas ocasiones necesitará acceder a las bloque de instrucciones tam bién podrem os usar variables
propiedades y m étodos de un objeto de forma m uy consecu­ y funciones ajenas al objeto, es decir, otras variables o fun­
tiva, haciendo que su código sea poco elegante y pesado de ciones que tengamos definidas en cualquier parte de nuestro
escribir. Por ejemplo: código.

126 127
<SCRIPT TYPE="text/javascript">
// Declaración de variable
var velocidad = 100;
I I Declaración de función
function subirVelocidad() {
velocidad += 20;
}
I I Sentencia with
with (miCoche) {
alert(color);
alert(marca);
alert(modelo);
acelerar(velocidad);
subirVelocidadO;
acelerar(velocidad);
}
</SCRIPT>

Tras ejecutar este script, se nos mostrarán mensajes con el


color, marca y modelo de nuestra instancia miCoche. A con­
tinuación se llama al método acelerar de la instancia con
la variable velocidad como parámetro, con valor 100. Acto
seguido se ejecuta una función ajena al objeto que incrementa
esa variable ve locidad y,para terminar, se vuelve a llamar al
método acelerar con su parámetro mostrando el valor 120.

128
Objetos de JavaScript

Dentro del núcleo de JavaScript existen varios objetos que


ya están definidos y tienen una serie de funcionalidades tre­
mendamente útiles en m uchos casos.
De cada uno de estos objetos expondrem os el constructor,
propiedades y m étodos que tenga asociados, así como ejem ­
plos de algunos de ellos para m ejorar su com prensión o
utilidad.
Todos los objetos predefinidos de JavaScript disponen del
método toStr ing (), que devuelve el objeto expresado como
una cadena, realizando para ello conversiones implícitas si
es necesario. Para hacer uso de él, basta con hacer la llamada
desde el objeto que nos interese: miObj eto.toString ().

7.1. Objetos envoltorio


Los objetos que vamos a ver en este apartado se tratan en
realidad de un envoltorio (wrapper) de los tipos de datos pre­
definidos (booleano, número y cadena o string), como ya ade­
lantamos en el capítulo 2. Con esto queremos decir que crear
una instancia de uno de estos objetos m ediante la sentencia
new sería lo mismo que declarar una variable de esos tipos
directamente con el valor, pudiendo por tanto éstas últimas
acceder a la mayoría de las propiedades y métodos de su ob­
jeto envoltorio.

7.1.1. Objeto Boolean


Como puede imaginar, este objeto expresa un valor como
un booleano, o lo que es lo mismo, como true o false.

129
C o nstru cto r 7.1.2. Objeto Number
Para crear una instancia debe hacer lo siguiente:
Este objeto nos permite crear instancias que tengan un valor
<SCRIPT TYPE="text/javascript"> numérico (entero o real).
// Objeto Boolean
var nombre__variable = new Boolean (valor) ;
C o nstru cto r
</SCRIPT>

Aquí debe tener cuidado puesto que la conversión al tipo Su constructor es m uy simple:
booleano no se realiza de una forma intuitiva: <SCRIPT TYPE="text/javascript">
// Objeto Number
• Si el valor es omitido o es 0, -0, nuil, cadena vacía (" "), var nombre_variable = new Number(valor);
valor booleano false, valor undefined o valor NaN, </SCRIPT>
entonces este objeto devuelve una instancia con valor
false. Al igual que ocurre con el objeto Boolean, en función del
• En cualquier otro caso, devuelve true. valor que se reciba como parámetro en el constructor se ob­
tendrán distintos resultados:
Advertencia: Tenga presente estas reglas porque casos como • Si no recibe un valor, devuelve un 0.
lacadena " f a l s e " no hacen que el objeto devuelva f a l s e • Si recibe un número (expresado como tal o en forma
como podríam os pensar, sino que obtenemos un t r u e . de string), entonces inicializa el objeto con ese valor. La
cadena vacía equivale a un 0.
Tabla 7.1. Ejemplos del constructor Boolean. • En caso de que reciba un valor no numérico, devuelve
NaN.
I Constructor Resultado • El valor false se interpreta como un 0 y true como
un 1.
new Boolean() false
new Boolean(1) true Tabla 7.2. Ejemplos del constructor Number.
new Boolean(O) false
Constructor Resultado
new Boolean(65) true
new Boolean(false) false new NumberQ 0
new Boolean(true) true new Number(1) 1
new Booleanf") false new Number(O) 0
new BooleanfO") true new Number(65) 65
new Boolean('T') true new Number(false) 0
new Boolean("true") true new Number(true) 1
new Boolean(''false") true new Number("") 0
new Boolean("0") 0
P ropiedades y m étodos new Boolean('T') 1
Este objeto no tiene ninguna propiedad o m étodo. No new Numberftrue") NaN
hem os empezado por el más completo, pero no se preocupe new Number("false”) NaN
que los siguientes traerán más sorpresas.

130 131
P rop ied ades y m étodos el valor de la instancia sino que devuelven el resultado de su
operación, por lo que si queremos usar éste en otra parte de
Este objeto (ahora sí) tiene una serie de propiedades, que lis­
nuestro código haría falta almacenarlo previamente.
taremos a continuación, con una peculiaridad: únicamente son
accesibles desde el propio objeto y no desde sus instancias.
[Aplicación JavaScript]
• MAX VALUE: Indica el m ayor núm ero que se puede
■ Propiedades de Number:
representar en JavaScript. _ Ilk MAX_VALUE: 1.7976931348623157e+308
• MIN VALUE: Lo m ism o, pero con el m enor núm ero MIN_VALUE: 5e-324
NaN: NaN
representable. POSITIVEJNFINITY: Infinity
NEGATIVE_INFINITY: -Infinity
• NaN (Not A Number): Valor especial, que ya vimos junto
con los tipos de datos, que indica que el valor no es un Aceptar

número.
• POSITIVE_INFINITY: Valor especial (Infinity) que [Aplicación JavaScript]
m
indica que el número es mayor que el máximo represen­
Propiedades de numero:
table (MAX_VALUE). MAX_VALUE: undefined
MIN_VALUE: undefined
• NEGATIVE_INFINITY: Valor especial (-Infinity) NaN: undefined
que indica que el núm ero es m enor que el m ínim o POSITIVEJNFINITY: undefined
NEGATIVEJNFINITY: undefined
representable (MIN_VALUE).
| Aceptar i
<SCRIPT TYPE="text/javascript">
// Instancia de Number
var numero = new Number(5); Figura 7.1. Propiedades del objeto Number y una instancia
// Propiedades del objeto Number del mismo.
alert("Propiedades de Number:" + "\n" +
"\tMAX_VALUE: "+ Number.MAX VALUE +"\n"+
"\tMIN_VALUE: "+ Number.MIN_VALUE +"\n"+
• toExponential (decimales): Convierte un valor
"\tNaN: " + Number.NaN + "\n" + en una expresión exponencial (e o E), con el número
"\tPOSITIVE_INFINITY: " + Number.POSITIVE_ de posiciones decimales especificada por el parámetro
INFINITY + "\n" + decimales.
"\tNEGATIVE_INFINITY: " + Number.NEGATIVE_ • toFixed (decimales): Ajusta el número de posiciones
INFINITY); decimales de un valor a las definidas por decimales,
// Propiedades de la instancia redondeando si se reduce la cantidad de decim ales
alert("Propiedades de numero:" + "\n" +
actual.
"\tMAX_VALUE: " + numero.MAX_VALUE +"\n"+
"\tMIN_VALUE: "+ numero.MIN_VALUE +"\n"+ • toPrecision (dígitos): Ajusta el número de dígitos
"\tNaN: " + numero. NaN + "\n" + totales de un valor (parte entera y decimal) a los especi­
"\tPOSITIVE_INFINITY: " + numero.POSITIVE_ ficados por digitos. Aquí también se redondea si se
INFINITY + "\n" + eliminan decimales.
"\tNEGATIVE_INFINITY: " + numero,NEGATIVE_
INFINITY); El parámetro de estos métodos debe ser siempre un nú­
</SCRIPT> mero positivo. Si se utiliza un número real, se omitirán sus
decimales.
Como puede ver en la figura 7.1, las propiedades no son ac­
cesibles desde las instancias creadas a partir del objeto.
Nota: Recuerde que lina variable con un valor numérico
Pasamos ahora a ver los métodos, donde ocurre justo lo
escrito directamente se comporta igual que una instancia,
contrario: sólo pueden ser utilizados desde las instancias.
además es la form a más común de escribirlas. Por tanto: v a r
Esto tiene sentido puesto que hace falta un valor sobre el que
x = n ew N u m ber (5 ) equivale a v a r x = 5.
aplicar las operaciones que realizan. Los métodos no modifican

132 133
En la tabla 7.3 podrá ver cómo funcionan los m étodos de Constructor Resultado
este objeto. Para los ejemplos se utilizará la variable numero
new String(false) "false"
con valor 53.27.
new String(true) "true"
Tabla 7.3. Ejemplos de los métodos de Number. new String("") "" (cadena vacía)
Resultado new String("0") "0"
Ejemplo
»-j ii
new String('T')
numero.toExponential(1) 5.3e+1
new StringC'true") "true"
numero.toExponential(3) 5.327e+1
new Str¡ng("false") "false"
numero.toFixed(l) 53.3 (redondeando)
numero.toFixed(2) 53.27 P ropiedades y m étodos
numero.toFixed(4) 53.2700
Todas las propiedades y métodos que se listan a conti­
numero.toPrecision(2) 53 nuación se utilizan siempre sobre las instancias que hayamos
numero.toPrecision(3) 53.3 (redondeando) creado de este objeto.
numero.toPrecision(4) 53.27 La lista de propiedades es corta... sólo una y fácil de en­
tender:

7.1.3. Objeto String • 1ength: indica el número de caracteres que contiene la


cadena.
El objeto String nos permite realizar operaciones, bastante <SCRIPT TYPE="text/javascript">
útiles, sobre cadenas de texto. // Instancia de String
var nombre = new String("Pepe");
C o nstru cto r alert(nombre.length); // veremos un 4
nombre = "Yolanda";
Para crear una instancia de este objeto se debe escribir lo
alert(nombre.length); // veremos un 7
siguiente: nombre =
<SCRIPT TYPE="text/j avas cript"> alert(nombre.length); // veremos un 0
I I Objeto String </SCRIPT>
var nombre_variable = new String(valor);
Tras este "duro esfuerzo" vamos con los métodos, que sí son
</SCRIPT>
unos cuantos. No los voy a listar uno a uno ya que se pueden
El valor que le pasemos al constructor será convertido a agrupar en cierta medida por su similitud funcional.
una cadena de texto en todos los casos. Si se omite, se creará
una cadena vacía. Nota: El primer carácter de una cadena se considera que está
en la posición cero (0). Deberemos tener esto en cuenta en
Tabla 7.4. Ejemplos del constructor String. algunos de los métodos del objeto S t r i n g .

Constructor Resultado • anchor (nombre),link (dirección): Crean un ancla


"" (cadena vacía)
y un enlace HTML respectivam ente (etiqueta <A>). El
new Str¡ng()
prim ero coloca el valor del parámetro nombre dentro
new String(1) *r del atributo ÑAME del ancla, y el segundo el valor de
new String(O) "0" dirección en el atributo HREF. El valor de la cadena
new String(65) "65" se coloca entre las etiquetas <A> y </A>.

135
134
b i g ( ) , b l i n k (), b o l d ( ) , f i x e d ( ) , i t a l i c s (), cadenas separadas. Si el parámetro opcional limite
s m a l l ( ) , s t r i k e ( ) , sub ( ) , s u p ( ) : Encierran el valor tiene un valor, entonces se devuelven tantas subcadenas
de la cadena entre las etiquetas H TM L de formato (en como indique.
el mismo orden): <BIG>, <BLINK>, <B>, <TT>, <I>, • substring(inicio, fin),substr(inicio, lon­
<SMALL>, <STRIKE>, <SUB> y <SUP>. El valor de la gitud) ,slice (inicio, fin): Extrae y devuelve
cadena se coloca entre la etiqueta y su cierre, la porción de la cadena que se encuentra entre las
f o n t c o l o r ( c o l o r ) , f o n t s i z e ( t a m a ñ o ) : Cambian posiciones inicio y fin o una cantidad de carac­
el color y el tam año de un texto HTM L a través de los teres (longitud) a p artir de la posición inicio.
atributos COLOR y SIZE de la etiqueta <FONT>. El color Si se om ite el segundo parám etro en estos m étodos,
puede expresarse com o una cadena ("Red"), un valor entonces se devuelve la parte entre inicioyel final
RGB (255,0,0) o un código hexadecim al (#FF0000). Por de la cadena.
otro lado, el tam año del texto se define m ediante un • match(expresión),replace(expresión, reem­
núm ero del 1 al 7, siendo el 1 el tam año más pequeño plazo), search (expresión): Estos métodos buscan
y el 7 el mayor. El valor de la cadena se coloca entre una coincidencia de expresión dentro de la cadena o,
las etiquetas <FONT> y </FONT>. en el caso de replace, sustituye la prim era ocurrencia
charAt(posicion), charCodeAt(posicion) : por el valor de reemplazo. En todas ellas la búsqueda
Devuelven el carácter y el código UNICODE del ca­ es sensible a m ayúsculas y minúsculas. El parámetro
rácter que se encuentre en la posición indicada por su expresión puede ser una cadena o una expresión
parámetro. El primer carácter está en la posición cero regular. Los valores devueltos son distintos en cada
uno:
<°>-
),
indexOf(texto, inicio lastlndexOf(texto, • match: devuelve el valor de expresión si lo en­
inicio): Devuelven la posición de la primera y úl­ cuentra y nuil en caso contrario.
tima coincidencia, respectivamente, de texto dentro • replace: devuelve una cadena con los reemplazos
la cadena. Si no se encuentra entonces se devuelve el realizados, si se encontraron coincidencias. Tenga en
valor -1. El parámetro inicio es opcional e indica la cuenta que sólo se reemplazará la primera ocurrencia
posición en la que se debe empezar a buscar. El método de la expresión especificada.
indexOf busca desde inicio hacia el final de la cadena • search: este método devuelve la posición donde
y lastlndexOf desde inicio hacia el com ienzo. se encuentra la primera ocurrencia de la expresión,
Además, ambos métodos diferencian entre minúsculas o -1 si no hay coincidencias. Es similar al método
y mayúculas. indexOf.
concat (cadenal, cadena2, ..., cadenaN): Une el • toLowerCase ( ) ,toüpperCase ( ) : Devuelve la cadena
valor de la cadena con el de las cadenas pasadas como con todos los caracteres en minúsculas o mayúsculas,
parámetros (se puede poner una o varias). Equivale a # respectivamente.
utilizar el operador sobre cadenas (+).
fromCharCode (codigol, codigo2, ..., co-
Truco: Los métodos que trabajan con posiciones como pará­
digoN): Construye una cadena a partir de una lista de
metro esperan un valor positivo pero en algunos es posible
valores UNICODE. Este método es exclusivo del objeto
utilizar también negativos. En estos casos, el valor -1 repre­
String y no puede ser utilizado desde una instancia
senta la última posición de la cadena, que equivale a escribir
del mismo. m iC a d e n a . l e n g t h - 1.
split (separador, limite): Divide la cadena en
un subconjunto de cadenas tomando el parámetro se­
parador como delimitador de cadenas. En este caso se En la tabla 7.5 veremos el funcionamiento de la mayoría de
devuelve un objeto Array (aprenderemos a usar este estos métodos. Para los ejemplos se utilizará la variable texto
objeto justo a continuación de String) con todas las con valor "JavaScript mola".

137
Tabla 7.5. Ejemplos de los métodos de String. Recuerde que estos métodos no m odifican la instancia, por
lo que debe almacenar el valor en una variable si quiere usar
I Ejemplo Resultado | el resultado posteriormente.
<SCRIPT TYPE="text/javascript">
texto.anchor("lista") <A NAME="lista">JavaScript mola</A>
// Instancia de String
texto.bold() <B>JavaScript mola</B> var texto = new String("JavaScript mola");
// Definición de variable
texto.charAt(O) J
var textoMayusculas;
texto.charAt(2) v // Uso de métodos de String
textoMayusculas = texto.toUpperCase();
texto.indexOf("a") 1
texto = texto.concat(" y mucho");
texto.indexOf("a", 4) 14 (busca desde "S" en adelante) alert(textoMayusculas + "\n" + texto);
</SCRIPT>
texto.indexOffz") -1 (no existe)
texto. lastlndexOffa") 14 Con el código propuesto verem os un mensaje con el texto
texto.lastlndexOf -1 (no existe, busca desde "J" hacia atrás) "JAVASCRIPT MOLA" seguido de "JavaScript mola y mucho"
("a", 0)
una línea por debajo. Como puede observar, se puede utilizar
la misma variable con la que creamos la instancia para alma­
texto.concat" JavaScript mola y mucho" cenar los resultados de los métodos.
(" y mucho")
texto.concat "JavaScript mola y mucho"
(" y mucho") 7.2. Objeto Array
String.fromCharCode "HOLA" (sólo objeto String)
(72, 79, 76, 65) Las variables de JavaScript norm alm ente alm acenan un
te x to .s p litf") Array con cadenas "JavaScript" único valor, el cual podem os recuperar cuando utilizamos su
y "mola" nombre dentro de una expresión. Esto se nos puede quedar
Java
corto en determinadas ocasiones, como por ejemplo si que­
texto.substring(0, 4)
remos almacenar por separado los platos del menú de un res­
texto.substring(4) Script mola taurante para después mostrarlos en nuestra página. Gracias a
texto.substr(4, 6) Script los arrays podremos almacenar todos estos platos en una única
texto.substr(11) mola variable como si ésta tuviera huecos o casillas que se rellenan
con los valores, permitiéndonos acceder a cada plato indivi­
texto.substr(-4) mola
dual con tan sólo indicar cuál es su hueco, es decir, la posición
texto, matchf'mo”) mo dentro del array. A esta posición se le denomina índice.
texto.match("z") nuil
texto, replace JS mola 7.2.1. Constructor
("JavaScript", "JS")
texto.replace JavaScript mola Para crear un array tenemos varios constructores:
("javascript", "JS") 1. new A r r a y ( ) : crea un array vacío, sin huecos donde
texto.searchfva") 2 almacenar nuestros datos. Esto es útil cuando no sa­
texto.search("z") -1 bem os la longitud inicial que tendrá el array cuando lo
utilicemos en nuestro código.
texto.toLowerCase() javascript mola 2. new Array (longitud): en este caso el array se crea con
texto.tollpperCaseQ JAVASCRIPT MOLA tantos huecos como indique el parámetro longitud.

139
138
3. new Array (valorl, valor2, valorN): con que hace alert de forma automática para poder representar
este constructor crearemos un array con tantos huecos el objeto como una cadena.
o posiciones como valores hayamos pasado como pa­ <SCRIPT TYPE="text/javascript">
rámetros y, además, dichos huecos irán rellenos con el // Declaración de array
valor correspondiente. var menú = new Arr a y ("Arroz", "Filete con patatas",
"Flan");
El tipo de datos de los valores almacenados en un array // Visualizar contenido
puede ser cualquiera, incluso puede ser distinto en cada una de alert("El menú de hoy es: " + menú);
las posiciones. En otros lenguajes, los arrays están forzados a que </SCRIPT>
los datos sean siempre del mismo tipo (entero, booleano, etc).

[Aplicación JavaScript]
Tabla 7.6. Ejemplos del constructor Array.

Constructor Resultado

new Array() Array vacío y sin posiciones.


new Array(5) Array con 5 posiciones vacías.
new Array("5") Array con 1 posición y 1 valor de Figura 7.2. Visualización del contenido de un array.
tipo cadena
new ArrayC'a", "b", "c") Array con 3 posiciones y 3 valores de Ahora bien, si queremos acceder a cada posición de un array,
tipo cadena. con el fin de obtener o modificar su contenido, tendremos que
new Array(1, 2, 3) Array con 3 posiciones y 3 valores de usar, a continuación del nombre de la variable, los corchetes
tipo numérico. e indicar la posición (índice) sobre la que queremos trabajar.
new Array("a”, 2, false) Array con 3 posiciones y 3 valores de La primera posición está representada por el índice 0, como
tipos distintos. ocurre con las cadenas.
<SCRIPT TYPE="text/javascript">
También tenemos la posibilidad de crear un array mediante el // Declaración de array
uso de corchetes ( [ ] ), lo que equivaldría a crear ima instancia sin var menú = new Arr a y ("Arroz", "Filete con patatas",
usar el constructor tal y como hemos visto en otros objetos. "Flan");
// Acceso a los valores
<SCRIPT TYPE="text/javascript">
alert("El menú de hoy es:\n" +
// Array con corchetes
"\t- " + menu[0] + "\n" +
var nombre_variable = []; // Array vacio "\t- " + menu[l] + "\n" +
var nombre_variable = ["a", "b", "c"]; // Array con 3
"\t- " + m e n ú [2]);
// posiciones y 3 valores de tipo cadena </SCRIPT>
var nombre_variable = [1, 2, 3]; // Array con 3
// posiciones y 3 valores de tipo numérico
var nombre variable = ["a", 2, false]; I I Array con 3
I I posiciones y 3 valores de tipos distintos
[Aplicación JavaScript] ■ E a
</SCRIPT> » El m enú de hoy es:
¿*\ - Arroz
- Filete con patatas

7.2.2. Trabajar con un array - Flan

f Aceptar |
Para ver el contenido de un array es suficiente con utili­
zarlo junto con un alert o ejecutar su método toString ()
Figura 7.3. Acceso al contenido de un array.
quedando los valores separados por comas. Esto último es lo

140 141
Una forma más cómoda de acceder a los valores es crear // Modificación de un valor
alert("El menú de hoy es: " + menú);
un bucle f o r , utilizando el contador como índice del array. menu[0] = "Macarrones";
Veam os el ejemplo anterior escrito con un bucle: alert("El menú de hoy es: " + menú);
<SCRIPT TYPE="text/javascript"> </SCRIPT>
// Declaración de variables
var menú = new Array("Arroz", "Filete con patatas",
[Aplicación JavaScript]
"Flan");
var mensaje = "El menú de hoy es:\n"; El menú de hoy es: Arroz,Ríete con patatas,Flan
// Acceso a los valores con un bucle ¿h
for(var i=0; i<3; i++) {
mensaje += "\t— " + menu[i] + "\n";
1
alert(mensaje);
</SCRIPT>

Obtendrem os el mismo resultado, nos conviene cuando


la longitud del array es alta o simplemente no la sabemos (ya
Figura 7.5. Modificación del contenido de un array.
veremos cómo controlar esto). Como ve, el contador comienza
en 0, para acceder a la prim era posición, y aumenta hasta el
valor 2, que corresponde a la tercera y última. Si el array tiene los huecos creados (se especificó una lon­
gitud o número de elementos) se rellenarán con los nuevos va­
Nota: Si intentamos acceder a una posición que no existe, lores, pero si no es así entonces se crean sobre la marcha aunque
entonces JavaScript nos devolverá un valor u n d e f i n e d . superen la longitud inicialmente fijada. De este modo es posible
tener un array vacío y asignarle tantos valores como queramos
<SCRIPT TYPE="text/javascript"> o tener un array de una longitud fijada y ampliarla.
// Declaración de array
<SCRIPT TYPE="text/javascript">
var menú = new Array("Arroz", "Filete con patatas",
// Declaración de array
"Flan"); var menú = new Array("Arroz” , "Filete con patatas",
// Acceso un valor que no existe
"Flan");
alert("El último plato de hoy es: " + menu[3]);
// Ampliación de un valor
</SCRIPT> alert("El menú de hoy es: " + menú);
menu[3] = "Café";
[Aplicación JavaScript] alert("El menú de hoy es: " + menú);
</SCRIPT>
El último plato de hoy es: undefined
¿h
| Aceptar \

Figura 7.4. Acceso a una posición inexistente en el array.

Para modificar el contenido de una posición basta con usar


el operador de asignación sobre una de las posiciones.
<SCRIPT TYPE="text/javascript">
// Declaración de array
var menú = new Array("Arroz", "Filete con patatas", Figura 7.6. Ampliación del contenido de un array con valores.
"Flan") ;

142 143
<SCRIPT TYPE="text/j avas cript">
[Aplicación JavaScript]
// Declaración de array
var menú = new A rr a y ();
// Ampliación de valores
alert("El menú de hoy es: " + menú); // vacio
menu[0] = "Arroz";
menu[l] = "Filete con patatas";
m e n ú [2] = "Flan";
alert("El menú de hoy es: " + menú);
</SCRIPT>

Figura 7.8. Array con dos posiciones libres.

7.2.3. Propiedades y métodos


El objeto Array sólo dispone de una propiedad:
• l e n g t h : nos indicará la longitud del array, en concreto
la posición del último elemento. Aquí no influye el que
los huecos tengan valor o no, sino que la posición exista
y sea accesible.
Figura 7.7. Ampliación del contenido de un array vacío.
<SCRIPT TYPE="text/javascript">
// Declaración de array
Debe saber que si ha especificado una longitud, no es obli­
var menú = new ArrayO;
gatorio rellenar el array completo, aunque las posiciones libres // Visualización de la longitud
estarán disponibles. alert("El menú tiene " + menú.length + " platos");
<SCRIPT TYPE="text/javascript"> I I vacio
// Declaración de array menú = new Array(3);
var menú = new Arr a y (5); alert("El menú tiene " + menú.length + " platos");
// Ampliación de valores // 3 posiciones vacías
alert("El menú de hoy es: " + menú); // 5 posiciones menú = new Array("Arroz", "Filete con patatas",
I I vacias "Flan");
menu[0] = "Arroz"; alert("El menú tiene " + menú.length + " platos");
menu[l] = "Filete con patatas"; // array con valores
menu[2] = "Flan"; m e n ú [4] = "Copa de licor"; // quinta posición
alert("El menú de hoy es: " + menú); // dos posiciones alert("El menú tiene " + menú.length + " platos");
I I libres // array con algunas posiciones vacías
</SCRIPT> </SCRIPT>

También hay que señalar que si, por ejemplo, dispone de A continuación se explicarán los métodos para este objeto:
un array de longitud 3 y añade un valor en la sexta posición • concat (arrayl, array2, ..., arrayN): Une el
(creada automáticamente), tendrá como resultado un array de array actual con los que se pasen como parám etros,
longitud 6 pero sin valores en los huecos cuarto y quinto. devolviendo el resultado en un único array.
• join (separador): Traslada todos los valores de un
Nota: No podemos acceder a una posición mayor a la longitud array a una cadena intercalando el carácter separador
del array, pero s í asignarle un valor y recuperarlo posterior­ entre ellos. Si no se especifica un separador se utiliza la
mente, puesto que se creará automáticamente. coma ( ,) por defecto.

144 145
• longitud_borrado: este método nos dice cuántos
valores vamos a borrar (puede ser ninguno, poniendo
un 0).
• valorl, valor2, ..., valorN: son opcionales
y representan los valores que se van a añadir en la
posición inicio, después de borrar la cantidad
longitud_borrado de elementos. Estos valores
no sobrescriben los existentes, sino que se intercalan
con ellos.
• reverse ( ) : Invierte el orden de todos los valores del
array, de forma que el prim ero pasa a ser el último y el
último el primero. No se devuelve un nuevo array sino
que modifica el actual.
• sort (función): Ordena alfabéticamente los valores
del array, m odificándolo en lugar de devolver uno
nuevo. Si se pasa una función como parámetro entonces
Figura 7.9. Longitud de distintos arrays. es utilizada para determinar cómo deben ordenarse los
valores. Esa función debe comparar valores de dos en
• pop ( ) : Devuelve y elimina el valor en la última posición dos y, para que el m étodo sort pueda "comprenderla",
de un array. Al mismo tiempo se borra la posición que tiene que devolver unos valores concretos:
ocupaba, reduciendo así la longitud del array. • Si el primer valor se considera menor que el segundo,
• push(valorl, valor2, ..., valorN): Añade uno o entonces hay que devolver -1 (o cualquier número
más valores al final del array y devuelve la longitud del negativo).
mismo. Si el array no dispone de posiciones suficientes • Si el primer valor se considera mayor que el segundo,
para almacenar los valores se crearán nuevas automá­ se devuelve un 1 (o cualquier número positivo).
ticamente. • Si ambos valores se consideran equivalentes, debe
• shift ( ) : Realiza la misma operación que pop, pero devolver un 0.
con el prim er valor.
En la tabla 7.7 puede encontrar algunos ejemplos de estos
• unshift(valorl, valor2, ..., valorN) : Se
métodos. En ellos tendremos definido el array semana con los
comporta igual que push, pero insertando uno o varios
valores "lunes", "martes" y "jueves".
valores al principio del array.
• slice (inicio, fin): D evuelve un nuevo array
que tiene únicam ente los valores que estén entre las Tabla 7.7. Ejemplos de los métodos de Array.
posiciones inicio y fin sin incluir éste, es decir, el
Ejemplo Resultado
último valor en añadirse será el de la posición fin-1. Si
se omite el segundo parámetro entonces se toman todos semana.concat(new Arrayfviernes")) lunes, martes, jueves,
los valores desde inicio hasta la últim a posición. viernes
• splice(inicio, longitud_borrado, valorl, semana.join(''-") lunes-martes-miércoles
valor2, ..., valorN): Añade y/o elimina valores
semana.pop() Array semana: lunes,
de un array. Este m étodo, a diferencia del resto, no
martes. Valor devuelto:
devuelve un nuevo array sino que modifica el actual.
jueves
La función de cada parámetro es la siguiente:
• i n i c i o : indica dónde vamos a comenzar a añadir / semana, pushfviem es") lunes, martes, jueves,
viernes
borrar valores.

146 147
Ejemplo Resultado I 7.2.4. Arrays multidimensionales
semana.shift() Array semana: martes, Los arrays con los que hemos trabajado hasta ahora eran
jueves. Valor devuelto: bastante simples ya que únicamente contenían una lista de
lunes valores. Esto se conoce como array unidimensional.
JavaScript nos permite almacenar en la posición de un array
semana, unshiftf'domingo") domingo, lunes, martes,
jueves
otro array, o lo que es lo mismo, almacenar una lista de valores
dentro de una única posición en lugar de tener un solo valor.
semana.slice(0, 2) lunes, martes
A esto se le denomina array bidimensional, aunque probable­
semana.slice(1, 3) martes, jueves mente le suene más el término matriz o tabla.
semana.slice(O) lunes, martes, jueves Así mismo, dentro de la posición de un array bidimensional
semana.splice(1, 1) Array semana: lunes, podremos volver a almacenar otro array, y así sucesivamente
jueves hasta llegar al mimero de dimensiones que queramos.
semana.splice(2, 0, "miércoles”) Array semana: lunes, Como todo esto explicado con palabras resulta un tanto
martes, miércoles, lioso, vamos a ir desarrollando un ejemplo hasta llegar a tener
jueves un array de tres dimensiones. Partiremos con unos arrays uni­
semana.splice(1, 1, "miércoles") Array semana: lunes, dimensionales que almacenan una lista de asignaturas:
miércoles, jueves <SCRIPT TYPE="text/javascript">
semana.reverse() Array semana: jueves, // Arrays unidimensionales
var asignaturas_letras = new Array("Historia",
martes, lunes
"Latín”, "Filosofía");
semana.sort() Array semana: jueves, var asignaturas_ciencias = new Array("Física",
lunes, martes "Química", "Matemáticas");
// Mostramos los arrays unidimensionales
alert(asignaturas_letras + "\n" +
Vamos a ver ahora un ejemplo del método s o r t empleando
asignaturas_ciencias);
una función que ordene las cadenas por su longitud en lugar </SCRIPT>
de alfabéticamente, como hace por defecto el método.
<SCRIPT TYPE="text/javascript"> [Aplicación JavaScript]
// Declaración de array
var semana = new Array("lunes", "miércoles", "jueves"); 'l Historia, Latín, Filosofía
// Declaración de función / *_) Física,Química,Matemáticas

function compararLongitud(cadenal, cadena2) {


if (cadenal.length > cadena2.length)
¡ Aceptar f
return 1;
else if (cadenal.length < cadena2.length) Figura 7.10. Arrays unidimensionales.
return -1;
else Para acceder a cada uno de los valores de un array, ya
return 0;
hemos visto que es tan sencillo como escribir un índice entre
}
// Ordenación por defecto. Saldrá "jueves, lunes, corchetes ( [ ] ):
// miércoles" <SCRIPT TYPE="text/javascript">
alert(semana.sort()) ; // Arrays unidimensionales
// Ordenación con función. Saldrá "lunes, jueves, var asignaturas_letras = new Array("Historia",
// miércoles" "Latín", "Filosofía");
alert(semana.sort(compararLongitud)); var asignaturas_ciencias = new Array("Física",
</SCRIPT> "Química", "Matemáticas");

148 149
// Mostramos los primeros valores por comas, así que como en este caso los valores son a su vez
a l e r t (asignaturas_letras[0] + "\nr + otro array JavaScript representa el prim er array, después una
a s i g n a t u ras_ciencias[0] ) ;
com a y por último el segundo array.
</SCRIPT> Para acceder a los valores debemos escribir dos parejas
de corchetes ([ ] [ ]), de manera que el primero sirve para ac­
[Aplicación JavaScript] B ceder a las posiciones del array bidimensional (dos posiciones
/» Historia
en nuestro ejemplo, que representan m añana y tarde) y el
i\\ Física segundo para las del array unidim ensional contenido en la
posición anterior (tres y cuatro posiciones por cada posición
| Aceptar j¡
del bidimensional). Vamos a ver esto en forma de matriz, que
seguro le será más fácil de visualizar.
Figura 7.11. Primer valor de los arrays unidimensionales.

Tabla 7.8. Array bidimensional aula_1 como una matriz.


H asta aquí no hay nada nuevo, así que vam os a subir de
nivel. Vamos a crear unos arrays bidimensionales que represen­ Turno Asignatural Asignatura2 Asignatura 3 Asignatura4
tarán las asignaturas que se imparten en un aula. Cada uno de
estos arrays (aulas) tendrá dos posiciones que van a simbolizar Mañana Física Química Matemáticas Biología
las asignaturas que se dan por la mañana y las que se dan poi Tarde Historia Latin Filosofía
la tarde. ¡Vamos al lío!
<SCRIPT TYPE="text/javascript"> Tabla 7.9. Array bidimensional aula_2 como una matriz.
// Arrays unidimensionales
var asignaturas_letras = new Array("Historia", Turno Asignatural Asignatura2 Asignatura3 Asignatura4
"Latín", "Filosofía"); , ,
var asignaturas_ciencias = new Array("Física , Mañana Historia Latín Filosofía
"Química", "Matemáticas", "Biología");
Tarde Física Química Matemáticas Biología
// Arrays bidimensionales
var aula 1 = new Array(asignaturas_ciencias,
asignaturas_letras); Con las tablas 7.8 y 7.9 como apoyo, y suponiendo que
var aula_2 = new Array(asignaturas_letras,
tenemos ya definidos todos los arrays necesarios en nuestro
asignaturas_ciencias) ;
// Mostramos los arrays bidimensionales
código, vamos a hacer las siguientes operaciones:
alert(aula_l + "\n" + 1. Las asignaturas que se imparten por la m añana en el
aula_2); aula 1.
</SCRIPT>
<SCRIPT T Y P E = "text/j avascri p t ">
// Mostramos los valores
[Aplicación JavaScript]
ale r t ( a u l a _ l [0]);
Física, Química, Matemáticas, Historia, Latín, Filosofía </SCRIPT>
Historia, Latín, Filosofía, Física, Química, Matematicas
¿h
[Aplicación JavaScript] m

! p Física, Química, Matemáticas


Figura 7.12. Arrays bidimensionales.

| Aceptar j
La figura 7.12 puede dar la im presión de que seguimos tra­
bajando con arrays unidimensionales con 6 posiciones cada uno,
pero eso es porque JavaScript muestra los valores separados Figura 7.13. Asignaturas de aula_1 por las mañanas.

151
150
2. Las asignaturas que se imparten por la mañana y por la 5. Número de asignaturas que se imparten por la tarde en
tarde en el aula 2. el aula 2.
<SCRIPT TYPE="text/javascript"> <SCRIPT TYPE="text/javascript">
// Mostramos los valores // Mostramos los valores
alert("Mañanas: " + aula_2[0] + "\n" + alert(aula_2[1].length); // Mostrará 4
"Tardes: " + aula_2[l]); asignatuas
</SCRIPT> </SCRIPT>

Bueno, ¿qué tal se ha dado? Sé que es un poco duro al


[Aplicación JavaScript]
m . principio pero poco a poco estas operaciones le parecerán más
¿ y Mañanas: Historia,Latín,Filosofía sencillas de entender.
/ « \ Tardes: Física,Química,Matemáticas
Ahora vamos con un último paso: arrays tridimensionales
j Acepta? ~ ] (suena a título de película, ¿verdad?). Para hacer esto vamos
a suponer que cada una de nuestras aulas están en un piso de
Figura 7.14. Asignaturas de aula_2 por las mañanas y tardes. un edificio. Para ello vamos a definir un nuevo array con dos
posiciones representando los pisos, por lo que cada posición
3. La primera asignatura que se imparte por la mañana en tendrá un aula como valor.
el aula 1. <SCRIPT TYPE="text/javascript">
<SCRIPT TYPE="text/j avascript”> // Arrays unidimensionales
// Mostramos los valores var asignaturas_letras = new Array("Historia”,
alert(aula_l[0][0]); "Latín", "Filosofía");
</SCRIPT> var asignaturas_ciencias = new Array("Física",
"Química", "Matemáticas", "Biología");
// Arrays bidimensionales
[Aplicación JavaScript] B var aula_l = new Array(asignaturas_ciencias,
Física
asignaturas_letras);
var aula_2 = new Array(asignaturas_letras,
asignaturas_ciencias);
| Aceptar |] // Array tridimensional
var plantas = new Array(aula_l, aula_2);
Figura 7.15. Primera asignatura de aula_1 por las mañanas. // Mostramos los arrays tridimensionales
alert(plantas);
4. La segunda asignatura que se imparte por la mañana </SC R IPT>

en el aula 2.
[Aplicación JavaScript]
<SCRIPT TYPE="text/javascript">
// Mostramos los valores
alert(aula_2[0][1]);
</SCRIPT>

[Aplicación JavaScript] ■ s Figura 7.17. Arrays tridimensionales.

¿ fs Lath Si se fija en la figura 7.17 verá que la representación de este


¡ Aceptar jj
array es la unión de los dos arrays bidimensionales separados
por tina coma. Vam os a ver también este array en forma de m a­
triz para que le sirva de ayuda en los ejemplos posteriores:
Figura 7.16. Segunda asignatura de aula_2 por las mañanas.

152 153
Tabla 7.10. Array tridimensional plantas como una matriz. 3. La primera asignatura que se imparte por la mañana en
la primera planta.
Planta Turno mañanas Turno tardes
<SCRIPT TYPE="text/javascript">
Primera Física, Química, Historia, Latín, Filosofía // Mostramos los valores
Biología, Matemáticas alert(plantas[0][0][0]);
</SCRIPT>
Segunda Historia, Latín, Filosofía Física, Químíca,
Matemáticas, Biología
[Aplicación JavaScript]

Entonces, para acceder ahora a un valor del array bidimen-


Física
sional (aulas) debemos escribir una pareja de corchetes ( [ ]
[ ] ) pero para alcanzar el valor de un array unidimensional | Aceptar |

(asignaturas) hay que escribir tres parejas ( [ ] [ ] [ ] ). Veamos


esto con ejemplos: Figura 7.20. Primera asignatura de la planta 1 por la mañana.
1. Las asignaturas que se imparten en la prim era planta.
4. La tercera asignatura que se imparte por la tarde en la
<SCRIPT TYPE="text/javascript"> primera planta.
// Mostramos los valores
<SCRIPT TYPE="text/javascript">
alert(plantas[0]);
// Mostramos los valores
</SCRIPT>
alert(plantas[0] [1] [2]) ;
</SCRIPT>
[Aplicación JavaScript]
[Aplicación JavaScript] m
jy ^ Filosofía

¡ Aceptar jj

Figura 7.18. Asignaturas de la planta 1.


Figura 7.21. Tercera asignatura de la planta 1 por la tarde.
2. Las asignaturas que se imparten por la m añana en la
primera planta. 5. Número de asignaturas que se imparten por la mañana
en la segunda planta.
<SCRIPT TYPE="text/javascript">
// Mostramos los valores <SCRIPT TYPE="text/javascript">
alert(plantas[0][0]); // Mostramos los valores
</SCRIPT> alert (plantas [1] [0].length);
</SCRIPT>

[Aplicación JavaScript] B

¿t3
| Aceptar ¡]

Figura 7.19. Asignaturas de la planta 1 por la mañana. Figura 7.22. Cantidad de asignaturas de la planta 2 por la mañana.

154 155
function mostrarNumeroParametrosO {
Espero que le haya quedado claro la forma de acceder a
alert(arguments.length);
las distintas dimensiones en cada uno de los casos. De todas }
formas le recomiendo que practique con sus propios ejemplos // Llamadas con distinto número de parámetros
para coger soltura en el manejo de arrays. mostrarNumeroParametros(); // Mostrará 0
mostrarNumeroParametros(1); // Mostrará 1
mostrarNumeroParametros("a", "b", false); // Mostrará 3
7.2.5. Arrays en elementos de JavaScript </SCRIPT>

Me gustaría comentarle brevemente un par de casos es­ Para ver todos los argum entos que se han pasado a la
peciales dentro de JavaScript en los que ciertos elementos se función podemos recurrir al bucle f o r para mostrarlos más
comportan como arrays. cómodamente.
<SCRIPT TYPE="text/javascript">
C adenas com o arrays
// Declaramos una función
En cierto modo podemos concebir una cadena como una function mostrarParametros() {
lista de letras o caracteres, pudiendo obtener (pero no m odi­ var valores = "Parámetros:\n";
ficar) cada uno de ellos de forma independiente, aunque no
for(var i=0; i<arguments.length; i++) {
valores += "\t- Parámetro " + i + ":
tendremos disponibles los m étodos asociados al objeto Array arguments[i] + "\n";
puesto que se trata de una instancia del objeto String. }
< SCRIPT TYPE="text/javascript"> alert(valores);
// Declaramos una cadena
// Llamadas con distinto número de parámetros
var mensaje = "Bienvenido";
// Acceso a caracteres como un array mostrarParametros();
alert(mensaje[0]); // Mostrará "B" mostrarParametros(1);
alert(mensaje[4]); // Mostrará "v" mostrarParametros("a", "b", false);
mensaje[0] = "b"; // No tendrá efecto </SCRIPT>
alert(mensaje[0]); // Mostrará "B"
</SCRIPT> [Aplicación JavaScript]

A rg u m en to s de una fun ció n com o un array


¿h
¿Creía que se m e había olvidado? Soy despistado, pero [Aplicación JavaScript]
cumplo con mi palabra. En el capítulo referente a las funciones
Parámetros:
se dijo que se podría controlar que los parámetros fuesen obli­ ¿h - Parámetro 0: 1

gatorios u opcionales, gracias al objeto arguments que nos


[Aplicación JavaScript]
proporciona JavaScript, el cual almacena en cada posición el
valor del parámetro situado en la misma posición. Además, , i '• Parámetros:
l}\ - Parámetro 0: a
sólo estará disponible dentro de cada función. - Parámetro 1: b
- Parámetro 2: false
No im porta si la función no tiene definido ningún pará­
metro o tiene un número menor de los que se le hayan puesto. \ Aceptar ¡

El objeto arguments albergará igualm ente todos los pará­


m etros que se indiquen en la llam ada a la función. Figura 7.23. Listado de parámetros mediante el objeto arguments.
Este objeto tampoco tiene los m étodos de Array, pero sí
su propiedad length, por lo que podrem os saber cuántos Si queremos que todos los parámetros de nuestra función
parámetros le llegan a una función. sean obligatorios para poder realizar las acciones, entonces
<SCRIPT TYPE="text/j avascript"> debemos comprobar que el número de argumentos que nos
// Declaramos una función llega es el mismo que esperamos.

157
156
<SCRIPT TYPE="text/javascript"> }
// Función con parámetros obligatorios if (arguments[1] == undefined) (
function sumar(numerol, numero2) { numero2 = 3;
if (arguraents.length = = 2 ) { }
return numerol + numero2; return numerol + numero2;
} else { )
return "No hay dos números"; // Llamadas con distinto número de parámetros
alert(sumar()); // Mostrará "Falta el primer número"
}
alert(sumar(5)); // Mostrará 8 (valor por defecto)
}
// Llamadas con distinto número de parámetros alert(sumar(5, 2)); // Mostrará 7
alert(sumar()); // Mostrará "No hay dos números" </SCRIPT>
alert(sumar(5)); // Mostrará "No hay dos números"
alert(sumar(5, 2)); // Mostrará 7
</SCRIPT> 7.3. Objeto Date
Por otro lado, para hacer que un parámetro sea opcional, y
poder darle un valor por defecto si queremos, tendremos que Dado que JavaScript no posee un tipo de dato específico
comprobar el valor de la posición correspondiente en el objeto para m anejar fechas, com o ocurre en otros lenguajes, nos
arguments. Si tiene un valor u n d e f i n e d significa que no lo ofrece como alternativa este objeto que nos permite manipular
hemos recibido. En el ejemplo, haremos opcional el segundo información acerca del año, mes, día, hora, minutos, segundos
número de la suma. y milisegundos.
La particularidad del objeto D ate es la forma que tiene de
<SCRIPT TYPE="text/javascript">
// Función con parámetros opcionales almacenar la fecha, ya que la representa como los milisegundos
function sumar(numerol, numero2) { que han pasado desde una fecha base que es el 1 de enero de 1970
if (arguments[1] = undefined) { a las 00:00:00. Aún así, el rango de fechas que puede manejar es
numero2 = 3; de -100000000 (-100 millones) hasta +100000000 (100 millones) de
} días relativos al 1 de enero de 1970 UTC (Universal Coordinated
return numerol + numero2; Timé). El UTC, o tiempo civil, es la zona horaria de referencia
} respecto a la cual se calculan todas las otras zonas del mundo y
// Llamadas con distinto número de parámetros
alert(sumar()); // Mostrará NaN porque numerol no es es sustituto del sistema GMT (Greenwich Mean Time).
// obligatorio No se asuste puesto que no tendrá que descifrar cada fecha
alert(sumar(5)); // Mostrará 8 (valor por defecto) a partir de los milisegundos. Este objeto también viene acompa­
alert(sumar(5, 2)); // Mostrará 7 ñado de métodos para hacernos esta tarea mucho más sencilla.
</SCRIPT> Los iremos viendo en este apartado.
Como ha visto, en caso de no pasar ninguno de los pará­ En la tabla 7.11 se listan los posibles valores que puede
metros, la suma se realizaría pero nos daría un resultado no tomar cada campo de la fecha, que se expresan con números
deseado (NaN), de m odo que tendríam os que realizar una enteros.
combinación de ambas restricciones: comprobar que el primer
parámetro nos ha llegado, no realizando la suma si no es así, y Tabla 7.11. Rango de valores para los campos de una fecha.
asignar un valor por defecto al segundo si tampoco lo hemos Campo Rango de valores
recibido.
<SCRIPT TYPE=”text/javascript"> Milisegundos 0-999
// Función con parámetros opcionales Segundos y minutos 0-59
function sumar(numerol, numero2) (
Horas 0-23
if (arguments[0] = undefined) {
return "Falta el primer número"; Día de la semana ■ 0 (domingo) - 6 (sábado)

159
158
Campo Rango de valores Constructor Resultado
Día del mes 1- 31 new Datef'Agosto 15, 2008") Fecha no válida (mes en
Mes 0 (enero) -11 (diciembre) español).
Año Desde 1900 new Date(2008, 7, 15) 15 de agosto de 2008.
new Date(2008, 7, 15, 13, 15, 34) 15 de agosto de 2008 a
7.3.1. Constructor las 13h 15min 34seg.

La sintaxis para crear una instancia de este objeto es bas­


tante simple:
7.3.2. Propiedades y métodos
<SCRIPT TYPE="text/javascript"> Este objeto no tiene ninguna propiedad por lo que pasa­
// Objeto Date remos directamente a ver sus métodos, que los agruparemos
var nombre_variable = new Date(fecha); en tres tipos de funcionalidad: obtención, asignación y trans­
</SCRIPT> formación.
El parámetro f e c h a puede ser cualquiera de estas expre­
siones: M étodos de obtención

• Vacío: Si no se pasa este parámetro, entonces se crea una • g e t T i m e ( ) : Con esto obtenemos la fecha tal y como
instancia con la fecha y hora actuales. Si le suena de otros la guarda el objeto D a te , es decir, expresada como el
lenguajes, sería el equivalente a la función now ( ) . número de milisegundos que han pasado desde la fecha
• Una cantidad de milisegundos: Se crea una fecha su­ base.
mándolos a la fecha base. • g e t M i l l i s e c o n d s (), g e t S e c o n d s (), g e tM i-
• "Mes_en_letras día, año horas:m inutos:segundos": El n u t e s ( ) , g e t H o u r s ( ) : Devuelven el campo corres­
mes debe estar escrito en inglés. Si se omite la parte co­ pondiente a los m ilisegundos, segundos, m inutos u
rrespondiente a las horas, minutos o segundos, tomarán hora, respectivamente, de la instancia actual.
valor 00 por defecto. • g e t D a t e ( ) , g e t D a y ( ) , g et M o n t h ( ) : Nos permiten
• "Año, m es, día": Estos valores deben ser num éricos obtener el día del mes, el día de la semana y el mes de la
enteros. instancia actual, representados siempre con un número
• "Año, mes, día, hora, minuto, segundos": Exactamente entero de acuerdo a lo visto en la tabla 7.11.
igual que el anterior pero ampliado para incluir la hora. • g e t Y e a r ( ) , g e t F u l l Y e a r ( ) : Devuelven el año de la
instancia actual. g e t F u l l Y e a r siempre lo hará como
Tabla 7.12. Ejemplos del constructor Date. un número de cuatro cifras mientras que g e t Y e a r , que
caerá en desuso, se comporta de diferente manera según
Constructor Resultado I el navegador (se utilizan como ejemplo dos de los más
utilizados):
new Date() La fecha y hora actuales.
• Tanto en Internet Explorer como FireFox, si el año
new Date(86400000) 2-enero-1970 a las OOh está comprendido entre 1900 y 1999, lo devolverá en
OOmin OOseg (milise­ forma de dos dígitos (00-99).
gundos de un día) • En Internet Explorer, obtendremos un número de
new D atefAugust 15, 2008") 15 de agosto de 2008 a las cuatro cifras en el resto de casos (1890 ó 2012).
i OOh OOmin OOseg. • En FireFox, si el año es anterior a 1900 nos dará
new DatefAugust 15, 2008 13:15:34") 15 de agosto de 2008 a los años de diferencia como un núm ero con signo
las 13h 15min 34seg. negativo (-10 equivale a 1890).

160 161
M étodos de tran sfo rm ació n
• En FireFox, los años a partir de 2000 nos dara un
número a partir de 100 (112 equivale a 2012). • par se ( fecha_cadena): Recibe una fecha expresada
• getUTCMilliseconds(), getUTCSeconds(), ge- como una cadena en inglés y devuelve el número de
tUTCMinutes (),getUTCHours(), getUTCDate(), milisegundos que han pasado desde la fecha base. Si
getUTCDay (),getUTCMonth(),getUTCFullYear (): no es posible interpretar la cadena como una fecha se
Funcionan exactam ente igual que sus análogos pero devuelve NaN. Este m étodo sólo puede ser llam ado
devolviendo el campo de acuerdo al UTC. desde el objeto Date y no desde sus instancias.
• qetTimezoneOf f set ( ) : Devuelve la cantidad de mi­ • UTC(año, mes, día, hora, minuto, segundo,
nutos de diferencia que existen entre el GM T y la fecha milisegundo): Toma la fecha indicada por los paráme­
de la instancia actual. Esto nos será útil para averiguar tros y halla el número de milisegundos que han pasado
la zona horaria en la que nos encontram os (pasando desde la fecha base de acuerdo al UTC. Los tres primeros
esos m inutos a horas). Si sale un valor negativo, -60 parámetros son obligatorios para usar este método (año,
por ejemplo, estaremos en la zona horaria GM i-KL bin mes, día) y el resto opcionales. También es un método
embargo, el mismo valor pero positivo (60), indicaría exclusivo del objeto Date.
que estam os en GMT-1. • toDateString () , toLocaleDateString ():
Devuelven la fecha sin inform ación sobre la hora, y
M étodos de asignación en form a de texto. Adem ás, toLocaleDateString
Los m étodos que verem os a continuación m odifican la ajusta los nom bres de los cam pos a la configuración
instancia con el valor resultante de la operación, asi que no de idiom a de la m áquina local sobre la que se ejecuta
el código.
devuelven ningún valor.
• toTimeString ( ) ,toLocaleTimeString ( ) : Similar
• setTime (milisegundos):E s t e método crea una fecha a los anteriores pero devuelven únicamente la parte
añadiendo o restando los milisegundos indicados a la correspondiente a la hora.
fecha base. • toGMTString(), toUTCString(), toLocaleS-
• setMilliseconds(mseg), setSeconds(seg, tring ( ) : Expresan la fecha y la hora en base al GM T,
mseg),setMinutes(min, seg, m s e g ) ,setHours UTC y configuración local respectivamente.
(hora, min, seg, mseg): Fija los campos corres­
pondientes a los m ilisegundos (mseg), segundos (seg), Vamos a ver algunos ejemplos de estos métodos, por lo
minutos (min) y hora. En todos estos m étodos el primer que utilizaremos una instancia hoy que contiene la fecha 13
parámetro es obligatorio y el resto son opcionales. de enero de 2009 17:23:55 y 356 milisegundos.
• setDate(día), setMonth(mes, día),setYear
año), setFullYear (año, mes, dia): Fija los campos Tabla 7.13. Ejemplos de los métodos de Date.
que corresponden al día del mes, el mes y el ano. Al igual
que los métodos anteriores, sólo es obligatorio el primer Ejemplo Resultado
parámetro. setYear sigue las mismas reglas sobre el
hoy.getTime() 1231863835256
año que explicamos con getYear y además esta cayendo
en desuso, por lo que es recomendable utilizar set Fu hoy.getMinutes() 23
HYear en su lugar. hoy.getDate() 13
• setUTCMilliseconds(mseg), s e t U T C S e c o n d s (
hoy.getDay() 2 (martes)
seg, mseg), setUTCMinutes(min, seg, mseg),
s e t U T C H o u r s (hora, min, seg, mseg),setUTCDate hoy.getYear() 2009 (Internet Explorer)
día), setUTCMonth(mes, día), setUTCFullYear ó 109 (FireFox)
año, mes, día): Realizan lo mismo que sus equiva­ hoy.getFullYear() 2009
lentes pero ajustadas al UTC.
163
162
var edad = parselnt(edadMilisegundos / 1000 / 60 /
Ejemplo Resultado i
60 / 24 / 365); // usamos parselnt para descartar
// los decimales
hoy.getTimezoneOffset() -120 (GMT +2) // Mostramos la edad
hoy.setT¡me(1500089) variable hoy: 1 de enero de 1970 alert(edadMilisegundos); // Mostrará 1114045200000
01:25:00:089 // mil isegundos
alert(edad); // Mostrará 35
hoy.setMonth(11) variable hoy: 1260721435256 (13 </SCRIPT>
diciembre 2009 17:23:55:356)
1177884000000 Si ahora quisiéramos realizar este cálculo utilizando fun­
hoy = Date.parse ciones del objeto fecha no basta con restar los años (método
("April 30, 2007")
getFullYear) puesto que deberíamos tener en cuenta si ya
hoy.toLocaleDateStringO martes, 13 de enero de 2009 ha cumplido años en la fecha actual o no. Para ello debemos
hoy.toUTCString() Tue, 13 Jan 200915:23:55 GMT seguir estos pasos:
(2h de diferencia)
1. Calculamos temporalm ente la edad mediante la resta
Date.parse(”Jan 2, 1970") 86400000 (GMT+0) de los años de ambas fechas.
2. Si el m es actual (m étodo getMonth) es posterior al
de n acim iento sign ifica que ya ha cum plido años,
7.3.3. Trabajar con fechas por lo que p od ríam os d ev olver la edad calcu lad a
A la hora de realizar operaciones con fechas, JavaScript en el paso anterior. En caso de que el m es actual sea
siem pre va a operar con los valores expresados en m ilise­ m enor que el de nacim iento significaría que no ha
gundos aunque nosotros podrem os recuperar después ese llegad o su cu m p leañ os tod av ía y ten d ríam os que
restar un año a la edad obtenida en el paso anterior
valor en el formato que m ás nos convenga.
En nuestros cálculos usarem os normalmente alguno de los y devolverla. Por últim o, si los m eses coinciden nos
operadores aritméticos (suma y resta) y los comparadores. quedaría por analizar la diferencia entre los días (en
Vamos a ver un ejemplo suponiendo que queremos calcular el paso siguiente).
la edad de una persona a partir de su fecha de nacimiento. Para 3. Aquí analizaremos la diferencia entre los días correspon­
ello tendremos que calcular la diferencia que existe entre el año dientes al mismo mes. Si el día actual (método getDate)
de su nacim iento y el actual usando el operador aritmético de es m enor al de nacimiento, restamos un año a la edad
la resta (-). La pega que existe al trabajar con fechas es que del paso 1 y la devolvemos. Por otro lado, si el día es
vamos a tener los valores expresados como milisegundos, por igual o mayor, la edad se quedaría como está y podría
devolverse.
lo que esta resta nos dará un valor en esas unidades y debe­
remos expresar en años. Ahora vamos a trasladar todos estos pasos a una función
que usaremos después en unos ejemplos:
Nota: Para pasar una fecha en milisegundos a otra unidad de
tiempo debemos tener en cuenta lo siguiente: 1 año son 365 <SCRIPT TYPE="text/javascript">
function calcularEdad(nacimiento) {
días, 1 día son 24 horas, 1 hora son 60 minutos, 1 minuto son
var hoy = new Da t e ();
60 segundos y 1 segundo 1000 milisegundos. var edad = hoy.getFullYear() - nacimiento.
getFullYear();
<SCRIPT TYPE="text/j avascript"> // Comparamos los meses
// Definimos las fechas if (hoy.getMonth() > nacimiento.getMonth()) {
var nacimiento = new Date(1975, 8, 30); / / N o hacemos nada porque ya es la correcta
// 30 septiembre 1975 } else if (hoy.getMonth() < nacimiento.getMonth()){
var hoy = new Date(); // 18 enero 2011 edad--; // Restamos un año porque no ha llegado
var edadMilisegundos = hoy - nacimiento; // el cumpleaños

164 165
} else (
// Comparamos los dias 7.4. Objeto Math
if (hoy.getDate0 < nacimiento.getDate()) (
edad— ; // Restamos un año porque no ha Hasta ahora podíam os realizar operaciones matemáticas
// llegado el cumpleaños
sencillas en JavaScript gracias a los operadores aritméticos,
}
pero en ocasiones necesitaremos hacer cálculos más complejos.
}
return edad; El objeto M a t h nos proporciona un buen surtido de propie­
} dades y métodos que nos permitirán satisfacer la mayoría de
</SCRIPT> nuestras necesidades dentro del código.
Vamos ahora a comprobar el funcionamiento de nuestra
función con un primer ejemplo en el que el cumpleaños todavía 7.4.1. Constructor
no ha llegado (fecha actual 18 de enero de 2011):
Este objeto no tiene constructor, por lo que todas sus pro­
<SCRIPT TYPE="text/j avascript"> piedades y métodos deben utilizarse directamente a través
// Definimos las fechas del objeto Math.
var nacimiento = new Date(1975, 8, 30);
// 30 septiembre 1975
var miEdad = calcularEdad(nacimiento); Truco: Recuerde que puede utilizar la sentencia wi t h (Ma t h )
I I Mostramos la edad para acceder más cómodamente a los elementos de este objeto.
alert(miEdad); // Mostrará un 35
</SCRIPT>
7.4.2.Propiedades y métodos
¡Bien! Todo ha funcionado como esperábamos. Veamos qué
pasa ahora si nuestro cumpleaños ya ha pasado (fecha actual Vamos a presentar ahora las propiedades de Math, que en
18 de enero de 2011). realidad son un conjunto de constantes matemáticas.
<SCRIPT TYPE="text/javascript"> • E: Representa la constante de Euler (2,718).
// Definimos las fechas • P I: Nos da el núm ero Pi (3,14159).
var nacimiento = new Date(1975, 0, 5); I I 5 enero 1975 • SQRT2: Con esta obtendríamos la raíz cuadrada de 2
var miEdad = calcularEdad(nacimiento); (1,414).
// Mostramos la edad
• SQRT1_2: La raíz cuadrada de Vi (0,707).
alert(miEdad); I I Mostrará un 36
</SCRIPT>
• LN2: Devuelve el logaritmo neperiano de 2 (0,693).
• LN10: El logaritmo neperiano de 10 (2,302).
¡Estamos en racha! Ahora queda la prueba de fuego. ¿Y • LOG2 E:Devuelve el resultado del logaritmo de E en base
si el cumpleaños es hoy mismo? (fecha actual 18 de enero de 2 (1,442).
2011 ). • LOG10E: Igual que el anterior, pero en base 10 (0,434).
<SCRIPT TYPE="text/j avascript"> <SCRIPT TYPE="text/javascript">
// Definimos las fechas // Propiedades del objeto Math
var nacimiento = new Da t e (1975, 0, 18); with(Math) {
I I 18 enero 1975 alert("Propiedades de Math:" + "\n" +
var miEdad = calcularEdad(nacimiento); "\tE: " + E + "\n" +
// Mostramos la edad "\tPi: " + PI + "\n” +
alert(miEdad); // Mostrará un 36 "\tRaiz cuadrada de 2 : " + SQRT2 + "\n" +
</SCRIPT> "\tRaiz cuadrada de 1/2: " + SQRT1_2 + "\n" +
"\tLogaritmo neperiano de 2 : " + LN2 + "\n" +
Todo perfecto, así da gusto. Ahora ya sabemos manejar "\tLogaritmo neperiano de 10: " + LN10 + "\n" +
fechas un poquito más. "\tLogaritmo de E en base 2: " + LOG2E + "\n" +

166 167
"\tLogaritmo de E en base 10: " + LOGIOE); • floor (numero): Igual que el anterior, pero devol­
} viendo el entero inmediatamente inferior.
</SCRIPT> • min(numerol, numero 2 ), max(nu m e r o l , nu-
m e r o 2 ) : Nos proporcionan el m enor o mayor valor de
sus dos parámetros.
[Aplicación JavaScript]
• pow(base, exponente): Nos calcula una potencia, es
Propiedades de Math: decir, devuelve el primer parámetro elevado al segundo
¿ t E; 2.718281828459045
Pi; 3.141592653589793 (baseexponmte).
Raíz cuadrada de 2: 1,4142135623730951
Raíz cuadrada de 1/2: 0,7071067811865476
• random ( ) : Nos dará un número real aleatorio entre 0
Logaritmo neperiano de 2: 0.6931471805599453
Logaritmo neperiano de 10: 2.302585092994046
Y 1-
Logaritmo de E en base 2: 1.4426950408889634 • round (numero): Redondea el parámetro al entero más
Logaritmo de E en base 10: 0.4342944819032518
cercano. Si numero no tiene decimales, o el prim ero
\ Aceptar i es menor o igual que 4, entonces el redondeo se hace
hacia abajo. En otro caso, se redondea hacia el siguiente
Figura 7.24. Propiedades del objeto Math. entero.
• sqrt (nume r o ) : Nos calcula la raíz cuadrada del pará­
Los métodos de Math nos servirán para realizar cálculos metro numero.
matemáticos más complejos que los que podíamos hacer hasta
ahora con los operadores: Tabla 7.14. Ejemplos de los métodos de Math.

• abs (numero): Nos devuelve el valor absoluto de nu­ | Ejemplo Resultado


mero.
• sin (ángulo),eos (ángulo),tan (ángulo) :Funciones Math.abs(1) 1
trigonométricas para calcular el seno, coseno y tangente. Math.abs(-3.5) 3
Su parámetro debe estar expresado en radianes en lugar Math.sin(5) -0.9589242746631385
de en grados. Tenga en cuenta que el valor devuelto por
Math.sin(Math.PI/2) 1
estos métodos será un valor entre -1 y 1.
• asin(numero), acos(numero), atan(numero): Math.acos(0.5) 1.0471975511965979
Realizan los cálculos trigonométricos arcoseno, arcoco- Math.acos(2) NaN (parámetro fuera de rango)
seno y arcotangente de su parámetro, el cual deberá ser Math.atan2(1, 3.2) 0.3028848683749714
un valor entre -1 y 1 (salvo para atan). Si el parámetro Math.exp(O) 1
está fuera de esos valores, se devuelve NaN. El valor del
Math.exp(1) 2.718281828459045 (E)
ángulo devuelto depende del m étodo que usemos:
• acos devuelve un ángulo entre 0 y Pi radianes. Math.log(2) 0.6931471805599453
• asin y atan nos darán un ángulo entre -Pi/2 y Pi/2. Math.log(O) -Infinity (no se puede calcular)
• atan2 (posicionY, posicionX): Nos devuelve el Math.ceil(3)
ángulo que forma, respecto al eje X, el punto situado en 3
Math.ceil(3.2) 4
las coordenadas indicadas como parámetros.
• exp (numero), log (numero): D evuelven, respec­ Math.ceil(3.9) 4
tivam ente, el resultad o de E elevado al parám etro Math.floor(3) 3
numero (Enumero) y el logaritmo neperiano (base E) del Math.floor(3.2) 3
parámetro.
Math.floor(3.9) 3
• ceil (numero): Devuelve el entero inm ediatamente
superior de numero si éste tiene decimales, o directa­ Math.min(2, 7)
2 .........................................................
m ente numero si no es así.
169
168
Veamos algunos ejemplos de patrones:
Ejemplo Resultado 1
1. Patrón que nos encuentre las coincidencias con "hol”
Math.max(2, 7) 7 seguido de una o más aes.
Math.pow(2, 3) 8 <SCRIPT TYPE="text/j avascript">
Math.randomO 0.048257613864494786 // Declaración de patrón
var miPatron = new RegExp("hola+");
Math.round(3) 3
</SCRIPT>
Math.round(3.2) 3
2. Patrón que nos encuentre las coincidencias con "hol"
Math.round(3.9) 4
seguido de una o más aes y sin distinción de mayúsculas
Math.sqrt(9) 3 y minúsculas.
Math.sqrt(5) 2.23606797749979
<SCRIPT TYPE="text/javascript">
// Declaración de patrón
var miPatron = new RegExp("hola+", "i");
7.5. Objeto RegExp </SCRIPT>

3. Patrón que nos encuentre las coincidencias con las líneas


Este objeto se utiliza para trabajar con las expresiones re­ que empiecen por "A".
gulares que definamos en nuestros scripts. En el apartado 2.3
<SCRIPT TYPE="text/javascript">
del capítulo 2 vimos cómo definir nuestras propias expresiones
// Declaración de patrón
regulares o patrones. var miPatron = new RegExp("AA");
</SCRIPT>
7.5.1. Constructor 4. Patrón que nos encuentre las coincidencias con un
número de dos dígitos.
El constructor de este objeto nos permitirá definir la ex­
presión regular que se aplicará sobre un texto y recoger los <SCRIPT TYPE="text/javascript">
resultados. La sintaxis sería la que sigue: // Declaración de patrón
var miPatron = new RegExp("\\d\\d");
<SCRIPT TYPE="text/javascript"> </SCRIPT>
// Objeto RegExp
var miPatron = new RegExp(patrón, modificadores); 5. Patrón que nos encuentre las coincidencias con una fecha.
</SCRIPT> <SCRIPT TYPE="text/javascript">
El patrón corresponde con un string que representa una ex­ // Declaración de patrón
var miPatron = new RegExp("\\d{2> —\\d{2>—\\d{4}");
presión regular válida, sin incluir las barras (/), mientras que
</SCRIPT>
los m odificadores son los mismos que vim os en el capítulo 2 y
pueden especificarse de forma opcional. Por tanto, es posible
definir un patrón y sus modificadores del mismo modo que si 7.5.2. Propiedades y métodos
lo escribiésemos como una cadena delimitada por barras (/),
siendo ambas sentencias correctas y equivalentes. Las propiedades de este objeto se centran principalmente en
la activación (con valor t r u e ) o desactivación (con valor f a l s e )
Advertencia: Si utiliza la barra invertida ( \) como parte del de algunos modificadores del patrón que se especificó en el cons­
patrón, recuerde que al tratarse de una cadena debe utilizar el tructor, aunque también hay otros con un fin diferente.
carácter de escape. Por tanto el carácter especial \d se deberá • g l o b a l : Sirve para fijar el modificador "g", para forzar
escribir como \ \ d y la propia barra invertida como \ \ \ que se sigan buscando coincidencias después de encon­
(quedando \ \ después de procesar la cad en a)._______________ trar la primera.

170 171
ignoreCase: Fija el m odificador "i", que elimina la • leftContext, rightContext: Nos permiten conocer
distinción entre m ayúsculas y minúsculas, los caracteres que están a la izquierda o derecha de la
multiline: A ctiva el m odificador "m", para permi­ última coincidencia.
tim os usar varios caracteres de posición (A y $) en el
patrón que definamos. Por otro lado, los métodos que contiene RegExp nos per­
lastlndex: Representa la posición (índice) dentro del mitirán aplicar el patrón con distintas finalidades.
texto donde se empezará a buscar la próxim a coinci­
• compile (patrón, modificadores): Nos permite
dencia. fijar un nuevo patrón en una instancia de RegExp y
<SCRIPT TYPE="text/javascript"> opcionalmente también sus modificadores. Si sólo se
// Declaración de patrón especifica el patrón, se pierden los m odificadores que
var miPatron = new RegExp("script", "g") ; tuviera.
// Mostramos los modificadores
• exec (texto): Aplica el patrón sobre el texto pasado
alert("global: " + miPatron.global + "\n" +
"ignoreCase: " + miPatron.ignoreCase + "\n" como parám etro y devuelve la cadena encontrada o
"multiline: " + miPatron.multiline); un valor nuil si no hubo coincidencias. Si se omite el
</SCRIPT> parámetro se tomará como texto el especificado a través
<SCRIPT TYPE="text/javascript"> de la propiedad input del objeto RegExp.
// Declaración de patrón • test (texto): Aplica el patrón sobre el parám etro
var miPatron = new RegExp("script", 1gm") ; texto pero únicam ente nos dirá si se encontraron
// Mostramos los modificadores
coincidencias (valor true) o no (valor false). Este
alert("global: " + miPatron.global + "\n" +
"ignoreCase: " + miPatron.ignoreCase + "\n" método es m uy rápido y se recomienda usarlo cuando
"multiline: " + miPatron.multiline); no necesitemos los valores encontrados. Si se omite el
</SCRIPT> parámetro, ocurre lo mismo que con el método e x e c .

Veamos algunos ejemplos utilizando /el/ como patrón y


[Aplicación JavaScript]
el pájaro saltó del nido" como texto donde aplicarlo.
global: true
¿h ignoreCase: false
multiline: false Tabla 7.15. Ejemplos de los métodos de RegExp.
[Aplicación JavaScript] w m Ejemplo Resultado
y» global: true
/*\ ignoreCase: false miPatron.compile("del") Se cambia el patrón a aplicar de
multiline: true
/el/ a /del/ sin modificadores.
¡ Aceptar |
miPatron.compile("del", "i") Se cambia el patrón a aplicar de
/el/ a /del/ y se activa el modifi
Figura 7.25. Propiedades del objeto RegExp.
cador "i".
miPatron.exec(texto) Devuelve "el” ya que se ha en
Las siguientes propiedades sólo están accesibles desde el ob­
jeto RegExp, aunque hace referencia a valores de la instancia. contrado coincidencia.
miPatron.test(texto) Devuelve true ya que se ha
• input: Nos permite fijar u obtener el texto sobre el que
encontrado coincidencia.
se aplica el patrón.
• lastMatch: Nos devuelve la última cadena encontrada
<SCRIPT TYPE="text/javascript">
mediante el patrón. // Declaración de patrón
• lastParen: N os devuelve la última coincidencia que var miPatron = new RegExpC'el", "g") ;
está encerrada entre paréntesis. // Definimos el texto donde aplicar el patrón

173
RegExp.input = "el pájaro saltó del nido";
// Aplicamos el patrón
miPatron.exec();
// Mostramos la última cadena encontrada ("el")
alert(RegExp.lastMatch);
<SCRIPT>

Com o ya se dijo en su m om ento, algunos m étodos del


objeto String pueden funcionar tam bién con expresiones
regulares escritas como una cadena. La forma de usarlos sería
la siguiente:
miTexto.nombre_metodo(/patrón/)

En concreto, los métodos search (patrón),match (pa­


trón) ,replace (patrón, reemplazo) y split (patrón,
limite) funcionan exactam ente igual recibiendo una ca­
dena o patrón com o parám etro. En la tabla 7.16 puede ver
algunos ejem plos con "el pájaro saltó del nido" com o valor
de miTexto.

Tabla 7.16. Ejemplos de los métodos de String con patrones.

Ejemplo Resultado

miTexto.search(/el/) Nos devuelve la posición 0, que


es donde está la primera ocurrencia.
miTexto.seach(/la/) Nos devuelve -1, ya que no hay
coincidencias.
miTexto.match(/el/) Nos devuelve un array con un valor
(el primer "el").
m¡Texto.match(/el/g) Nos devuelve un array con dos valores
(los correspondientes a "el" y "del").
m¡Texto.replace(/el/, "El") Nos devuelve el texto modificando "el"
por "El".
miTexto.replace Nos devuelve el texto modificando "el”
(le\lg, "El") por "El" y "del" por "dEI".
miTexto.split(/del/) Obtenemos un array con los valores
"el pájaro saltó" y " nido"
miTexto.split(/del/, 1) Obtenemos un array con el valor
"el pájaro saltó"
miTexto.split(/a/) Obtenemos un array con los valores
"el páj", "ro s" y "Itó del nido"
miTexto.split(/a/, 2) Obtenemos un array con los valores
"el páj" y "ro s"

174
8
Objetos del navegador
(DOM)

Aunque ya comentamos algo en la introducción del libro,


no está m al refrescar un poco qué es esto del DOM.
Cuando creamos una página Web nos limitamos a poner
etiquetas que delimitan cada uno de los elementos que tendrá
la página: cabecera, cuerpo, párrafo, tabla, etc. Sin embargo,
el navegador debe "pintar" esa página para que el usuario
pueda conocer su contenido, interpretando todas las etiquetas
y creando a la vez una jerarquía de objetos que representan
los elementos que la componen. Esta jerarquía es el Modelo de
Objetos del Documento, más conocido como DOM (Document
Object Model).
Esto nos será m uy útil como programadores en JavaScript
ya que gracias al DOM podrem os acceder a cada elemento
de la página y obtener o modificar sus propiedades a nuestro
antojo.
Una vez que conozca la jerarquía de objetos, puede con­
sultar un gráfico resumen en el apéndice D, al final de esta
guía.

8.1. Compatibilidad entre navegadores


A pesar de que el DOM sigue unos estándares definidos por
el W3C ( World Wide Web Consortium h t t p : //www. w3 . o rg ),
sus objetos no siempre están definidos exactamente igual de
un navegador a otro o incluso entre versiones del mismo na­
vegador. Se podría decir que aprovechan para implementar su
propia interpretación del DOM llegando hasta el extremo de
añadir nuevos objetos que, obviamente, sólo son reconocidos
por ese navegador concreto. Por tanto, será tarea del progra-

175
mador tener que salvar esas posibles incompatibilidades o im- 8.2.2. Propiedades
plementaciones distintas para asegurar que el script se ejecutará
correctamente en el mayor número posible de navegadores. A continuación veremos la mayoría de las propiedades que
Lam entablem ente, todos estos esfuerzos no harán más que tenemos a mano con el objeto window, que no son pocas:
complicar y "ensuciar” nuestro código.
Pero veamos el lado bueno. No siempre se utilizan esas • l e n g t h : fija o devuelve el núm ero de marcos de la
propiedades u objetos extra y, actualmente, la m ayor parte ventana actual.
del DOM es com ún a todos los navegadores. Sólo necesitará • ñame: fija o devuelve el nom bre de la ventana que nos
tener algo de cuidado cuando esté programando en DHTML servirá para referimos a ella en el código. No lo confunda
(Dynamic HTM L) ya que hace un uso intensivo del DOM. con el título de la página que aparece en la parte superior
En los apartados siguientes veremos los objetos principales izquierda.
que form an el DOM. Si quiere conocer el detalle de los objetos • m en ubar: Nos devuelve un objeto que representa la
de más bajo nivel (capas, textos, tablas, etc.) podrá encontrarlos barra de menú del navegador (ver figura 8.1).
en cualquier libro relacionado con DHTML. • t o o l b a r : Nos devuelve un objeto que representa la
barra de herramientas del navegador (ver figura 8.1).
• s t a t u s b a r : Igual que el anterior pero con la barra de
estado (ver figura 8.1).
8.2. Objeto window • d e f a u l t S t a t u s : N o s permite fij ar u obtener el mensaj e
por defecto que se muestra en la barra de estado. Esta
Estam os ante el objeto estrella del DOM, puesto que es el propiedad no es compatible en FireFox por defecto.
más alto dentro de toda la jerarquía y el encargado de repre­ • s t a t u s : Nos permite modificar el texto de la barra de
sentar la ventana del navegador donde se está visualizando estado. Esta propiedad no es compatible en FireFox por
la página. Si utilizamos un navegador que maneje pestañas defecto.
(como FireFox o Internet Explorer 8), cada una de ellas tendrá • s c r o l l b a r s : Nos devuelve el objeto que simboliza las
su propio objeto window ya que en definitiva se trata de pá­ barras de desplazamiento (ver figura 8.1).
ginas distintas.
Para obtener sus colecciones de objetos, propiedades o mé­
todos no es necesario hacer referencia siempre a window ya
que JavaScript nos permite esta pequeña comodidad al tratarse
del más alto de la jerarquía.

8.2.1. Colecciones de objetos


Como verem os en otros objetos de JavaScript, window
contiene a su vez otros objetos.
• fr ame s : Se trata de un array con la colección de fram es o
marcos (etiquetas < F R A M E > o < I F R A M E > ) que contenga
la página. Podemos acceder a ellos a través de su posi­
ción en el array o su nombre (atributo ÑAME).
var miFrame = window.frames[0];
var miFrame = window.frames["menú"];

En realidad un fram e es un objeto window, por lo que tendrá


las mismas propiedades y métodos que él. Figura 8.1. Barras de un navegador.

176 177
. location, history, document: Nos devuelven os • opener: Hace referencia a la ventana que abrió la ac­
objetos location, history y document los cuales tual (ventana emergente o pop-up). Si la ventana no fue
verem os más adelante en este capítulo de forma rndi- abierta por otra, obtendremos un valor undef ined.
• el o sed: Nos indica si la ventana está cerrada o no a
. outi'erHeight, outerWidth: Establece o devuelve el través de un valor booleano.
tamaño, en pixels, del espacio de toda la ventana en ______________________________________________ outerW idth
vertical u horizontal, respectivamente. Este valor incluye
las barras de desplazam iento, de herram ientas, etc (ver

. innírHeight, innerWidth: O btiene la altu ra o


anchura, en p ixels, del espacio donde se visu aliza ou terH e lg h t
propiam ente la página (ver figura 8.2). Este valor tiene
en cuenta las barras de desplazam iento, si hubiera,
pero excluye todas las dem ás (m enú, herram ientas,
estado, etc.).
ou terW id th

Figura 8.3. Propiedades de espacio del objeto window con pestañas.

Truco: Para hacer que las propiedades d e f a u l t S t a t u s y


s t a t us funcionen con FireFox, se debe modificar su configura­
ción accediendo al URL aboutxonfig y cambiando el valor de la
clave d o m .d ± s a b l e _ w i n d o w _ s t a t u s _ c h a n g e a falso.

El siguiente ejemplo nos permite cambiar el tamaño de la


ventana actual ajustando el número de pixels por el valor que
queramos:
<SCRIPT TYPE="text/javascript">
// Redimensionamos la ventana
• parent: Se refiere a la ventana donde esta situado el window.outerWidth - 640;
marco (<FRAMESET>) en el que estam os trabajando. window.outerHeight = 480;
En caso de no haber m arcos en la página, equivale a la </SCRIPT>

. t c f !; üevueWc^ía ventana que se encuentra un nivel por 8.2.3. Métodos


encima del marco actual. Si no hay m arcos en la pagina,
se devuelve la propia ventana. Entre los métodos del objeto window encontraremos mu­
• self: Se refiere a la ventana actual (es sim ilar chas funciones de utilidad para aportar m ás dinam ism o a
sentencia this que vim os con los objetos). nuestras páginas.

178 179
alert (mensa je): ¿Le suena;)? ¡Ahora sabe de dónde • toolbar:Nos permite indicar si la ventana tendrá
viene! Por si no lo recuerda, muestra un mensaje en un barra de herramientas o no.
cuadro de diálogo con el botón Aceptar, • menubar: M uestra u oculta la barra de menús de la
conf irm (mensaje): Muestra un mensaje en un cuadro nueva ventana.
de diálogo pero, a diferencia de alert, m uestra los • location: Nos permite mostrar u ocultar la barra
botones Aceptar y Cancelar. Además, nos permite saber de direcciones en la nueva ventana.
sobre qué botón se ha hecho clic, ya que devuelve un • di rector i es: Nos deja decidir si la ventana tendrá
valor true para A ceptar y false para Cancelar, botones de dirección o no.
prompt (mensaj e , valor_por_defecto): Este • scrollbars: Nos deja indicar si la nueva ventana
método es una extensión de conf irm, ya que incluye tendrá barras de desplazamiento o no.
una caja de texto para recoger un valor escrito por el • status: Nos permite controlar la visibilidad de la
usuario, el cual además es devuelto. Opcionalm ente barra de estado.
podemos indicar un valor que será mostrado por defecto • resizable: Permite establecer si la nueva ventana
en la caja de texto cuando se muestre el mensaje. Si el podrá ser cambiada de tamaño (con el ratón) o no.
usuario hace clic sobre C ancelar obtendremos un valor • fullscreen: Nos deja indicar si la ventana se verá
nuil. a pantalla completa o no.
focus ( ) ,blur ( ) : Establece o retira el foco de un objeto. • width, height: Con esto establecemos el ancho o
Se dice que un objeto tiene el foco cuando lo estamos alto que tendrá la ventana, en pixels.
utilizando (por ejemplo, escribiendo en un cuadro de • top, lef t: Podemos indicar la distancia, en pixels,
texto) y lo pierde cuando dejamos de usarlo. Con estos a la que estará la ventana respecto al lado superior
métodos podemos forzar estas situaciones. o izquierdo de la pantalla.
moveBy (x, y): Desplaza la ventana el número de pí- Este método devuelve un identificador para la ventana
xeles indicados. La x indica el desplazamiento horizontal que hemos abierto (para poder hacer referencia a ella
y la y el vertical. después) o un valor nul 1 si la ventana no pudo abrirse
,
moveTo ( x y): M ueve la ventana a una posición con­ (por ejemplo a causa de un bloqueo de ventanas emer­
creta. gentes). Se puede decir que el método open crea una
resizeBy(x, y): Redim ensiona la ventana tantos instancia del objeto window.
píxeles como indiquen los parámetros. La x se refiere a • cióse ( ) : Cierra la ventana actual.
la anchura y la y a la altura. • pri n t ( ) : M anda im prim ir la página que estem os
resizeTo (x, y): Establece una anchura y altura con­ viendo.
cretas a la ventana. • setlnterval(expresión, milisegundos): Evalúa
scrollBy (x, y): Realiza un desplazam iento hori­ una expresión continuamente después de que hayan
zontal y/o vertical de tantos píxeles como m arquen los pasado el número de milisegundos especificados. Este
parámetros. método nos devuelve un identificador, que podrá ser
scrollTo (x, y): Realiza un desplazamiento hori­ utilizado para detener su ejecución.
zontal y/o vertical hasta una posición concreta, • setTimeout(expresión, milisegundos) : Evalúa
open (URL, nombre, parámetros): Crea una nueva una expresión una única vez después de esperar a que
ventana (normalmente un pop-up) en la que se carga pasen el número de milisegundos indicados. Este m é­
el URL especificado. Esta ventana recibe tam bién un todo también nos devuelve un identificador para poder
nombre para identificarla y, opcionalmente, una serie cancelar esta ejecución antes de que ocurra.
de parámetros que se pasan como una cadena de pares • clearlnterval(identificador),clearTimeout
"propiedad=valor" separados por comas, siendo yes o identificador): Cancelan respectivam ente la eje­
1 valores positivos y no o 0 los negativos. Pasemos a cución de setlnterval y setTimeout a través del
ver cuáles podemos incluir: identificador pasado como parámetro.

181
"width=500,height=300");
window.openCmi_pagina.html", "ventana2", "width=500,
ISoyunílert! II ( J ) Sov un c n n t a « c a p ta s ? height=300,top=5,left=5”);
window.openCmi_pagina.html", "ventanal", "toolbar=l,
|-teWI Fft^tarl [CancelarJ menubar=0,location=0");
</SCRIPT>
[ A p lic a c ió n J a v a S c r ip t ]
Ahora usaremos los m étodos que evalúan una expresión
I Me conocen como prompt j
pasado un plazo de tiempo.
jS o y un valor por defecto) I <SCRIPT TYPE="text/javascript">
\ Aceptar j | Cancelar \ I I Muestra un mensaje cada 5 segundos
setlnterval("alert(\"Riiiiiinggg\")", 5000);
Figura 8.4. Ejemplos de los métodos alert, confirm y prompt. </SCRIPT>
<SCRIPT TYPE="text/javascript">
// Muestra un mensaje a los 5 segundos
A continuación veremos algunos scripts que utilizan los m é­ setTimeout("alert(\"¡Se acabó el tiempo!\")", 5000);
todos del objeto window referentes a los cuadros de diálogo. </SCRIPT>

<SCRIPT TYPE="text/javascript"> Tam bién es posible usar funciones que ya estuvieran defi­
// Capturamos el botón nidas en nuestro script.
var boton = confirm("¿Quieres continuar? ),
if (boton) { <SCRIPT TYPE="text/javascript">
alert(" ¡Adelante!") ; // Declaración de función
function saltarAlarma() (
} else (
alert("Hasta pronto"); alert("Riiiiiinggg");
) }
// Ejecuta una función cada 5 segundos
</SCRIPT>
<SCRIPT TYPE="text/javascript"> setlnterval("saltarAlarma()", 5000);
// Capturamos el texto </SCRIPT>
var texto = prompt("¿Qué navegador utilizas?"); <SCRIPT TYPE="text/javascript">
if (texto == nuil) { // Declaración de función
alert ("Vale, sólo era una pregunta..."); function mostrarMensáje() {
alert("¡Se acabó el tiempo!");
} else f
alert("Utilizas: " + texto); >
// Ejecuta una función a los 5 segundos
}
setTimeout("mostrarMensaje()", 5000);
</SCRIPT>
</SCRIPT>
Con los siguientes ejemplos podremos crear nuevas ven­
tanas con o sin parámetros adicionales. El código que sigue ejecutará la función mostrarCuenta-
Atras cada segundo hasta que la variable segundos valga
<SCRIPT TYPE="text/j avascript"> cero, momento en el cual se cancelará la repetición de setln­
// Ventana nueva con opciones por defecto
terval automáticamente.
var ventana = window.open("mi_pagina.html",
"ventanal") ; <SCRIPT TYPE="text/javascript">
if (ventana == nuil) { var segundos = 5;
alert("No se pudo abrir la ventana"); var temporizador;
} // Declaración de función
</SCRIPT> function mostrarCuentaAtras () {
<SCRIPT TYPE="text/javascript"> if (segundos > 0 ) {
// Ventana nueva con opciones personalizadas alert("Quedan " + segundos + " segundos para el
w i n d o w . op e n ("mi_pagina.html", "ventanal". lanzamiento");

183
182
segundos— ;
1 else { Otra manera de usar funciones con parámetros, es incluir
clearlnterval(temporizador); una llamada normal dentro de un sentencia function.
alert(" ¡Ignición!");
<SCRIPT TYPE="text/javascript">
} // Declaración de función
} function mostrarMensaje (mensaje) {
// Ejecuta una función cada segundo
alert(mensaje);
temporizador = setlnterval("mostrarCuentaAtras()",
}
1000); // Ejecuta una función cada 5 segundos
</SCRIPT> setlnterval(function(){ mostrarMensaj e ("Riiiiiinggg")
Este otro código ejecutará la función mostrarMensaje }, 5000);
</SCRIPT>
después de 10 segundos, a menos que pulsemos sobre el botón
<SCRIPT TYPE="text/javascript">
A ceptar del cuadro de diálogo que se muestra. // Declaración de función
<SCRIPT TYPE="text/javascript"> function mostrarMensaje(mensaje) {
var temporizador; alert(mensaje);
var boton; }
I I Declaración de función I I Ejecuta una función a los 5 segundos
function mostrarMensaje () { setTimeout(function(){ mostrarMensaje("Riiiiiinggg")
alert("¡Ya estoy aqui!” ); ), 5000);
} </SCRIPT>
// Ejecuta una función a los 10 segundos
De esta forma, además podrem os incluir m ás líneas de
temporizador = setTimeout("mostrarMensaje()", 10000);
// Controlamos la cancelación del timeout
código que necesitemos ejecutar dentro de esas llamadas pro­
boton = confirm("¿Cancelamos la espera?"); gramadas. Como ejemplo, haremos dos llamadas a la función
if (boton) { mostrarMensaje con dos textos distintos. El efecto es que
clearTimeout(temporizador); se m ostrarán ambos mensajes, tino a continuación del otro,
} pasados 5 segundos.
</SCRIPT>
<SCRIPT TYPE="text/javascript">
Así mismo, también podremos usar funciones con paráme­ // Declaración de función
tros. Para ello podemos escribir como una cadena la llamada function mostrarMensaje(mensaje) {
con sus correspondientes valores. alert(mensaje);
}
<SCRIPT TYPE="text/javascript"> // Ejecuta una función a los 5 segundos
// Declaración de función setTimeout(function(){ mostrarMensaje("Riiiiiinggg");
function mostrarMensaje(mensaje) { mostrarMensaje("Y más riiiing!"); }, 5000);
alert(mensaje); </SCRIPT>
}
// Ejecuta una función cada 5 segundos
setlnterval ("mostrarMensaje (V'RiiiiiingggV) ", 5000) ;
</SCRIPT> 8.3. Objeto navigator
<SCRIPT TYPE="text/javascript">
// Declaración de función Con este objeto podremos acceder a información acerca del
function mostrarMensaje(mensaje) { navegador que está utilizando el usuario para ver la página.
alert(mensaje); Esto nos será de utilidad para tomar decisiones dentro de
} nuestro código ya que sabremos de antemano qué cosas po­
// Ejecuta una función a los 5 segundos
setTimeout ("mostrarMensaje (V'RiiiiiingggV) ", 5000) ;
drían no funcionar en el navegador. Por ejemplo, si detectamos
</SCRIPT> que el usuario está utilizando FireFox 1.0, haremos que nuestro
código no ejecute el método resizeTo del objeto window ya
184 185
"browserLanguage: " + navigator.browserLanguage
que no lo reconocería, o si el navegador es Opera M ini es re­ + "\n" +
comendable que nuestra ventana no tenga unas dimensiones "systemLanguage: " + navigator.systemLanguage +
muy grandes ya que el usuario estará usando un Smartphone, "\n" +
con una resolución más baja que un ordenador. "userLanguage: " + navigator.userLanguage +
"\n" +
"language: "+ navigator.language + "\n" +
8.3.1. Propiedades "cpuClass: "+ navigator.cpuClass + "\n" +
"platform: "+ navigator.platform + "\n" +
Gracias a esta lista de propiedades podemos obtener bas­ "cookieEnabled: " + navigator.cookieEnabled);
tante inform ación sobre el navegador del usuario, aunque </SCRIPT>
puede que algunos valores le sorprendan por no ajustarse a
lo que esperaba: M ensaje de pagina w eb

appCodeName: HoíAí
• appCodeName: Devuelve el nom bre del código del J \ appName: MKrosoft Internet Explorer
appMnorVersIon: 0
appVersion: 4.0 (compatible,' M5IE 8.0; Windows fff 5.1; Trident/4.0; .NET CLR 2.0,50727; .NET CLR i, 1.4322; .NET CLR 3.0.4506.2152; .NET a R
navegador. 3.5.30729)
userAgent: Mo2*a/4.0 (compatible; MSIE 8.0; Windows NT S .l; Trident/4.0; .NET a R 2.0.50727; .NET a R 1.1.4322; .NET a R 3.0,4506.2152; .NET
• appName: N os dice el nombre del navegador. CLR 3.5,30729)
browserLanguage: es
syjternlanguage: es
• appMinorVersion: Nos dice la versión de la última userLanguage: es
language: undefned
revisión del navegador. cpuClass: x86
píatform: Wln32
cooteEnaMed: true
• appVersion: Nos proporciona inform ación acerca de
la versión del navegador.
• userAgent: D evuelve la cabecera com pleta del n a­
Figura 8.5. Propiedades del objeto navigator en Internet Explorer 8.
vegador que se envía en cada petición H T T P . Esta
propiedad contiene los valores de las propiedades
[Aplicación JavaScript] |x ]
appCodeName y appVersion.
• browserLanguage: Devuelve el idioma del navegador. I appCodeName: Moztfo
. * ■ appName: Netscape
appMinorVersion: undefined
• systemLanguage: Nos dice el idiom a por defecto del appVersion: 5.0 (Windows; es-ES)
userAgent: Mozia/5.0 (Windows; ü; Windows NT 5.1; es-ES; rv:1.9.2.1B) Gecko/201106M
sistema operativo del usuario. Firefox/3.6.18
browserLanguage: undefined
• userLanguage: Indica el idioma preferido del usuario systemLanguage: undefined
userLanguage: undefined
para el sistema operativo que está utilizando. language: es-ES
cpuClass: undefined
• language: Nos devuelve el idioma del navegador. platform: Wm32
cookieEnabled: true
• cpuClass: Nos ofrece información acerca del tipo de | Acc-ptar ¡j
procesador que tiene el usuario.
• platform: Indica la plataforma del sistema operativo. Figura 8.6. Propiedades del objeto navigator en Firefox 3.6.
• cookieEnabled: Perm ite saber si el navegador tiene
activadas las cookies o no. Aunque tendremos un capítulo appCodeName: Mozilla
dedicado a ello, una cookie es una inform ación que se appName: Opera
guarda en el navegador en las visitas a páginas Web. appMinorVersion:
appVersion: 9.80 (J2ME/MIDP;OperaMini/6.24093/25.729, U; es)
<SCRIPT TYPE="text/j avascript"> userAgent 0pera/9.80 (J2M EM TDP; Opera Mrni/6.24093/25.729; U ; es) Presto/2.5.25 Version/10.5454
// Mostramos las propiedades browserLanguage: es-ES
systemLanguage undefined
alert("appCodeName: " + n a vigator.appCodeName +
userLanguage: es-ES
"\n" + language: es-ES
"appName: " + navigator. appName + "\n" + cpuClass: undefined
"appMinorVersion: " + navigator.appMinorVersion platform: Pike v7.8 release 517
+ "\n" + cookieEnabled: true
"appVersion: " + navigator.appVersion + "\n" +
"userAgent: " + navigator.userAgent + "\n" +
Figura 8.7. Propiedades del objeto navigator en Opera Mini 6.

187
"availHeight: " + screen.availHeight + "\n" +
Nota: No todas estas propiedades están disponibles en todos "colorDepth: " + screen.colorDepth);
los navegadores, por lo que debemos tener esto en cuenta si </SCRIPT>
vamos a utilizarlas dentro de nuestro código.
[ A p lic a c ió n J a v a S c r ip t ]

/» width; 1680
8.3.2. Métodos ( * ^ height: 10S0
avaHWidth: 1600
avaüHdght: 1020
colorDepth: 32
La verdad que el número de métodos de este objeto no es
| Aceptar
muy amplio ya que no podemos modificar ninguna de las ca­
racterísticas del navegador, de modo que nos tendremos que
Figura 8.8. Propiedades del objeto screen.
conformar con uno.
• javaEnabled ( ): Nos indica si el navegador tiene acti­
vado el soporte para Java (que no JavaScript) mediante
8.5. Objeto history
un valor booleano.

Este objeto, que es una propiedad de window, se encarga


8.4. Objeto screen de almacenar el historial de visitas del navegador, es decir, una
lista de las páginas por las que hem os estado navegando. Su
Mediante el objeto s c r e e n podremos obtener información principal utilidad reside en la posibilidad de movernos hacia
acerca de la configuración de pantalla del usuario que está delante o atrás dentro de esa lista.
viendo nuestra página. Únicam ente tendrem os disponibles
unas pocas propiedades y, desafortunadamente, ningún m é­ 8.5.1. Propiedades
todo.
Sólo tendremos disponible una propiedad para el historial
de páginas.
8.4.1. Propiedades
• length: Devuelve la cantidad de sitios que hay dentro
Podrem os conocer algo más sobre la configuración del
del historial.
usuario, por si necesitam os realizar algún ajuste en nuestro
código.
• width, height: Nos indican los pixels de ancho y alto 8.5.2. Métodos
que tiene la resolución actual.
Los métodos de history son los que realm ente nos ayu­
• availWidth, availHeight: Nos devuelve la anchura
darán a desplazarnos por las páginas del historial.
y altura que queda libre en el área de trabajo del escri­
torio, es decir, resta al ancho o alto total el espacio que • back (),forward (): Carga la página inmediatamente
ocupan las barras de herram ientas que tengam os en anterior o posterior a la actual. Esto equivale a hacer
nuestro sistema operativo. clic sobre el botón Atrás o Adelante de nuestro nave­
• colorDepth: Nos permite conocer la profundidad de gador.
color, en bits, de la pantalla del usuario. • go (posicion): Carga una página específica que está
<SCRIPT TYPE="text/javascript"> en la posición indicada dentro del historial. El parámetro
// Mostramos las propiedades posicion puede ser un entero (negativo para páginas
alert("width: " + screen.width + "\n" + anteriores, positivo para posteriores) o una cadena que
"height: " + screen.height + "\n" + represente un URL.
"availWidth: " +- screen.availWidth + "\n" +

189
188
Truco: El método b a c k equivale a la llamada g o ( - 1 ) hostname mediante dos puntos ( :) . El puerto por de­
fecto para servidores Web es el 80 y no es común verlo
reflejado en el URL.
Páginas Páginas • host: Devuelve el nombre del servidor (hostname) y
anteriores posteriores el núm ero del puerto (port).
• protocol: Nos indica el protocolo que se ha usado para
acceder al servidor (normalmente HTTP).
<SCRIPT TYPE="text/javascript">
back() forward() with(location) {
alert("href: " + href + "\n" +
go(-2) go(-1) go(1) go(2) "hostname: " + hostname + "\n" +
"pathname: " + pathname + ”\n" +
Figura 8.9. Representación de los métodos de history. "hash: " + hash + "\n" +
"search: " + search + "\n" +
"port: " + port + "\n" +
8.6. Objeto location "host: " + host + "\n" +
"protocol: " + protocol);
}
Este objeto está representado por una propiedad del objeto </SCRIPT>
window y contiene el URL actual, del cual podremos obtener
una serie de valores que nos pueden ser de utilidad en algunos [Aplicación JavaScript] fX |
de nuestros scripts.
| href: http://www.miservldor.com:8080/prueba.html?buscar=1#ancla
„j L/. hostname: www.miservidor.com
pathname; /prueba.html
hash: #ancla
8.6.1. Propiedades search: ?buscar-l
port: 8080
host: www.miserYidot.com:8080
protocol! http:
Gracias a estas propiedades podrem os "destripar" el URL
| Aceptar ~~|
en varias partes para usar la que más se ajuste a nuestras ne­
cesidades. Figura 8.10. Propiedades del objeto location.
• href: Devuelve el URL completo. Tam bién podemos
reemplazarlo para dirigim os a otra página. <SCRIPT TYPE="text/javascript">
• hostname: Nos devuelve únicamente la parte del URL // Redireccionamos a otra página del mismo
que hace referencia al nombre o dirección IP del servidor // servidor
donde está alojada la página. location.href = "mi_pagina.html";
• pathname: Contiene la ruta que se sigue, dentro del </SCRIPT>
servidor W eb, hasta alcanzar la página actual. <SCRIPT TYPE="text/javascript">
// Redireccionamos a otra Web
• h a sh : Nos devuelve la parte del URL que hay después
location.href = "http://www.miweb.com";
de la almohadilla (#). Esto representa un enlace o ancla </SCRIPT>
(anchor).
• search: Nos devuelve la parte del URL que hay después
del signo de interrogación (?). A esto se le conoce como 8.6.2. Métodos
consulta o query string, ya que es donde se pasan valores
de una página a otra. Su función principal es la de interactuar con un URL.
• port: Nos indica el puerto por el que hemos accedido • a s s i g n (U R L): Carga un nuevo URL. Se creará una
al servidor. Esto viene indicado a continuación del nueva entrada en el objeto h i s t o r y .

190 191
El acceso a cada objeto individual se realiza mediante su
• replace (URL): Reemplaza el URL actual por otro. No
posición en el array o nombre (atributo ÑAME).
crea una nueva entrada en history sino que reemplaza
la actual. var miAncla = d o c u m e n t .a n c h o r s [0];
• reload ( ) : Recarga la página actual. Es lo mismo que var miFormulario = d o c u m e n t .forms["formNuevoUsuario"];
var milmagen = d o c u m e n t .images["logo"];
pulsar F5 en el navegador.
var miEnlace = d o c u m e n t .l i n k [3];
<SCRIPT TYPE="text/javascript">
// Redireccionamos a otra página Los objetos anchor, image y link los veremos en este ca­
lo c a t i o n . a s s i g n ("mi_pagina.html"); pítulo, mientras que al objeto form le dedicaremos un capítulo
</SCRIPT> aparte ya que es más complejo.
<SCRIPT TYPE="text/javascript">
// Obtenemos la hora actual
var ahora — new Date() ; 8.7.2. Propiedades
// Mostramos la hora
alert(ahora); • cookie: Nos devuelve en forma de cadena los valores
// Recargamos la página dentro de 5 segundos de todas las cookies que tenga el documento.
setTimeout("location.reload()", 5000) ; • doma i n: Nos indica el nombre del servidor donde está
</SCRIPT> alojado el documento.
• lastModif ied: Nos dice la fecha de la última modifi­
cación del documento.
8.7. Objeto document • referrer: Indica el URL del documento que llamó al
actual, a través de un enlace.
Cuando visualizamos una página W eb, todos sus elementos • title: Se trata del título del documento que aparece
(texto, imágenes, enlaces, form ularios...) quedan representados en la parte superior izquierda de la ventana del nave­
y accesibles para nuestro código dentro del objeto document. gador.
Por tanto, podremos añadir contenido a la página o modificarlo • URL: Devuelve el URL del docum ento actual. Es lo
a nuestro antojo. mismo que la propiedad location.href.
<SCRIPT TYPE="text/javascript">
8.7.1. Colecciones de objetos with(document) {
a l e r t (" cookie: " + cookie + "\n" +
Al igual que window, este objeto contiene a su vez una "domain: " + domain + "\n" +
colección de otros objetos. "lastModified: " + lastModified + "\n" +
"referrer: " + referrer + "\n" +
• anchors: Se trata de un array con todas las anclas "title: " + title + "\n" +
(ianchors) del documento. Estos elementos se identifican "URL: " + URL);
por la etiqueta <A> y tienen definido el atributo ÑAME. )
Esta colección de objetos se m antiene por tem as de </SCRIPT>
compatibilidad con versiones anteriores.
• f orms: Contiene todas las referencias a los formularios [Aplicación JavaScript] |X

(<F0RM>) de la página, dentro de un array. cookie:

• images: Aquí están recopiladas todas las imágenes domain: www.mlserYldor.cofn


lastModified: 0 5 /0 8 /20 11 1 3 :4 3 :5 7
referrer:
representadas con la etiqueta <IMG>. title: Página de prueba
URL: http ://www. mlservidor. cqm: 8080/prueba.htm l?buscar«l #ancla
• links: Contiene todos los enlaces de la página, como un
array. Se identifican por la etiqueta <AREA> o <A> pero | Aceptar j
con el atributo HREF definido. N o los confunda con los
Figura 8.11. Propiedades del objeto document.
anchor, que deben tener el atributo ÑAME definido.
193
192
8.7.3. Métodos 8.8. Objeto anchor
• write (texto), w r i t e l n (texto): Escribe texto Este objeto engloba todas las propiedades y métodos que
HTM L en el documento. El m étodo writeln añade tienen los enlaces internos al documento, también llamados
además un salto de línea (<BR>) al final del texto que anclas o anchor. Dentro de una página Web están identificadas
hayam os pasado como parámetro. con la etiqueta <A> y tienen un valor en el atributo ÑAME, sin
• open ( ) : Permite escribir sobre el documento mediante importar el resto de atributos. Esto es así para poder mantener
los m étodos write o writeln una vez que el docu­ la compatibilidad con versiones antiguas de JavaScript.
m ento ha sido cargado.
• cióse ( ) : Finaliza la escritura sobre el docum ento,
abierta mediante el método open.
8.8.1. Propiedades
• getElementByld (identif icador): Devuelve el Las propiedades de este objeto representan básicamente
primer elem ento del documento cuyo atributo ID coin todos los atributos HTML que puede tener. Salvo que se in­
cida con el parámetro identif icador. dique lo contrario, podremos, por tanto, obtener cómo modi­
• getElementsByName (nombre): Devuelve un array de ficar el valor de los siguientes atributos:
elementos cuyo atributo ÑAME coincida con el indicado.
• getElementsByTagName(etiqueta):Devuelve un • id : Identificador del ancla (atributo ID).
array de elementos cuya etiqueta sea la misma que la • ñame: N ombre del ancla (atributo ÑAME).
• t a r g e t : Ventana o marco donde se cargará el ancla
especificada por el parámetro.
(atributo TARGET).
Nota: Los métodos w r i t e , w r i t e l n , o p e n y c i ó s e en • t e x t : Esta propiedad es únicamente de lectura, y nos
ningún momento modificarán el fichero físico sino c¡ue solo permite saber el texto que contiene el ancla (lo que ve
el usuario en la página).
cambiarán el texto visible en pantalla.___________ __________
• innerHTML: Es igual que el anterior, pero nos permite
<SCRIPT TYPE="text/javascript"> además modificar ese texto.
// Escribimos algo en la página Veamos un ejemplo con un sencillo anchor:
document.write("Esto es un texto <B>en negrita
</B>."); <A ID="lstPropiedades" NAME="listado" TARGET="_self">Ver
</SCRIPT> listado de propiedades</A>
<Div ID="capal" TITLE="CapaPrueba">Esto es una <SCRIPT TYPE="text/javascript">
capa HTML</DIV> with(document.anchors["listado"]) {
<DIV ID="capa2" TITLE="CapaFondo">Esto es otra alert("id: " + id + "\n" +
capa más</DIV> "nombre: " + ñame + "\n” +
<SCRIPT TYPE="text/javascript"> "destino: " + target + "\n" +
// Recogemos un elemento de la página "texto (text): " + text + "\n" +
var elemento = document.getElementById("capal"); "texto (innerHTML): " + innerHTML);
// Mostramos su atributo title ("CapaPrueba ) t
alert(elemento.title); </SCRIPT>
</SCRIPT>
<SCRIPT TYPE="text/javascript"> La página en http://localhost dice: 1
// Recogemos una colección de objetos /# ' id: ^P ro p ied ad e s ¡
¿*\ nombre: listado ¡
var elementos = d o c u m e n t . destino: _setf '
getElementsByTagName("DIV"); texto (text): Ver listado d e propiedades
texto (InnerHTML): Ver listado de propiedades
// Mostramos cuántos hay (2)
alert("Hay " + elementos.length + " elementos | Aceptar j

DIV");
</SCRIPT> Figura 8.12. Propiedades del objeto anchor.

195
8.8.2. Métodos • text: Nos permite saber el texto del enlace (sólo lec­
tura).
Este objeto sólo cuenta con dos métodos referentes a la • innerHTML: Nos permite obtener y modificar el texto
posesión del foco. del enlace.
• focus ( ) ,blur ( ) : Hacen que reciba o pierda el foco, <A ID="lstPropiedades" HREF="#propiedades">Ver
respectivamente. listado de propiedades</A>
<SCRIPT TYPE="text/javascript">
with(document.links[0]) {
alert("id: " + id + "\n" +
8.9. Objeto link "URL: " + href + "\n" +
"destino: " + target + "\n" +
Mediante este objeto podrem os tener acceso a todos los "servidor: " + hostname + "\n" +
enlaces externos al documento o página actual. Se consideran "ruta: " + pathname + "\n" +
objetos l i n k todos los elementos HTML con etiquetas <AREA> "hash: " + hash + "\n" +
"consulta: " + search + "\n" +
y los <A> con el atributo HREF definido (aunque tengan tam­
"puerto: " + port + "\n" +
bién valor en ÑAME). "servidor y puerto: " + host + "\n" +
"protocolo: " + protocol + "\n" +
8.9.1. Propiedades "texto (text): " + text + "\n" +
"texto (innerHTML): " + innerHTML);
La lista de propiedades que tiene este tipo de objeto esrmuy }
</SCRIPT>
similar a la que vim os para location pero aplicadas sobre el
enlace, y también com parte algunas con anchor.
[Aplicación JavaScript]
• id: Identificador del enlace (atributo ID). | id: IstPropiedades
• href: Devuelve el URL completo del enlace (atributo URL: http://ww w.m iservidor.com :8080/prueba.hM ?buscar=l4!propledades
destino:
servidor: www.miservidor.cotn
HREF). , ruta: /prueba,html
• target: Ventana o marco donde se cargara el enlace hash: ¿p ropiedades
consulta: ?buscar«*l
puerto: 8080
(atributo TARGET). servidor y puerto: www.mtserv¡dor.corn:8080
protocolo: http:
• hostname: Nos devuelve únicamente la parte del URL texto (text): Ver listado d e propiedades
texto (sinerHTML): Ver listado d e propiedades
que hace referencia al nombre o dirección IP del servidor
\ Aceptar ' j
donde está alojada la página destino.
• pathname: Contiene la ruta que se sigue hasta alcanzar
Figura 8.13. Propiedades del objeto link.
la página destino.
• hash: Nos devuelve la parte del URL que hay después
de la almohadilla (#). Esto representa un enlace o ancla <A ID="lnkHome" HREF="inicio.html'T>Ir a página
principal</A>
(anchor). <SCRIPT TYPE="text/javascript">
• search: Nos devuelve la parte del URL que hay despues with(document.links[0] ) {
del signo de interrogación (?), también llamado consulta alert("id: " + id + "\n" +
o query string. "URL: " + href + "\n" +
• port: Nos indica el puerto por el que vamos a acceder "destino: " + target + "\n" +
"servidor: " + hostname + "\n" +
al servidor destino.
"ruta: " + pathname + "\n" +
• host: Devuelve el nombre del servidor (hostname) y
"hash: " + hash + "\n" +
el número del puerto (port). "consulta: " + search + "\n" +
• protocol: N os indica el protocolo que vam os a usar "puerto: " + port + "\n" +
para acceder al servidor (normalmente HTTP). "servidor y puerto: " + host + "\n" +

196 197
"protocolo: " + protocol + "\n" + imagen, es decir, incluyendo el nom bre del servidor y
"texto (text): " + text + "\n" + la ruta hasta la imagen.
"texto (innerHTML): " + innerHTML);
w id th , h e i g h t : Como podrá adivinar, nos permite
} conocer y cam biar la anchura y altura de la im agen
</SCRIPT>
(atributos WIDTH y HEIGHT).
a l t : Corresponde con el texto alternativo que se muestra
[Aplicación JavaScript]
al usuario cuando la im agen no puede ser cargada
i. id: kikHome
UW-: Wlp://www.mservidor.corn:8C)aD/inicio.html
(atributo ALT).
destino:
servidor: www.mtservidor.com t i t l e : Afecta al texto que se muestra sobre la imagen
ruta: /irtdo.html
hash: cuando ponem os el cursor sobre ella (atributo TITLE).
consulta:
puerto: 8080
servidor y puerto: www.m¡servidor.com:8080 <IMG ID="imgLogo" NAME="logo" SRC="imagenes/logo.
protocolo: http: jpg" WIDTH="120" HEIGHT="45" ALT="Logo de la
texto (text): Ir a página principal
texto (innerHTML): Ir a página principal empresa" TITLE="Este es nuestro logo"X/IMG>
<SCRIPT TYPE="text/javascript">
with(document.images[0]) {
Figura 8.14. Propiedades del objeto link. alert("id: " + id + "\n" +
"nombre: " + name+ "\n" +
"URL: " + src+ "\n" +
8.9.2. Métodos "ancho: " + width+ "\n" +
"alto: " + height + "\n" +
Dada la similitud de l i n k con el objeto a n c h o r , cuenta "texto alternativo: " + alt + "\n" +
"texto sobre imagen: " + title);
con los mismos métodos que éste.
>
• f o c u s ( ) , b l u r ( ) : H acen que reciba o pierda el foco, </SCRIPT>
respectivamente.
[Aplicación JavaScript]

id: imgLogo

8.10. Objeto image nombre: logo


UU.: http://www.mlservidor.com:8080/¡magenes/logo.jpg
ancho: 120
alto: 45
texto alternativo: Logo de la empresa
A través de este objeto seremos capaces de acceder y m a­ texto sobre imagen: Este es nuestro logo

nipular ciertas características de una imagen contenida en la L..-c£Ptá.; 1


página. No se puede hacer gran cosa, pero siempre está bien
contar con ello. Figura 8.15. Propiedades del objeto image.
Este objeto no cuenta con ningún m étodo, así que veremos
tínicamente sus propiedades.

8.10.1. Propiedades
• id : Se corresponde con el identificador de la imagen
(atributo ID).
• ñame: Nos da acceso al nom bre del objeto (atributo
ÑAME).
• s r c : Con esta propiedad podrem os m anipular el URL
de la imagen que se muestra (atributo SRC). Cuando
se recupera su valor se muestra el URL completo de la

199
9
Formularios

En este capítulo verá una de las principales utilidades de


JavaScript, al m enos teniendo en cuenta el alcance que tiene
esta guía: la posibilidad de controlar los form ularios de una
página.
La aparición de JavaScript en la program ación Web fue
motivada, en parte, por la necesidad de incluir un mecanismo
de control sobre los formularios directamente en el lado cliente
para así evitar cargar en exceso el servidor, liberándolo además
de esas tareas.
Un formulario HTM L permite recolectar inform ación pro­
porcionada directam ente por el usuario que visita nuestra
página para después utilizarla en nuestro sitio Web. El tipo
de inform ación que se puede recoger es m uy variada, siendo
desde datos personales hasta una lista de la compra.

9.1. Formularios en HTML


En este apartado se explicará cómo crear un formulario en
nuestra página, así como los elementos que puede contener.
No pretendo que sea un manual detallado, pero sí veo acon­
sejable desarrollarlo para que conozca todas las partes y ca­
racterísticas de un formulario de cara a controlarlas después
con JavaScript.

9.1.1. Formulario
Dentro de una página W eb pueden existir m ultitud de
elementos, y uno de ellos son los formularios. Para incluir
un formulario en nuestra página debemos utilizar la etiqueta

201
<FORM> al in d o y </FORM> al final. Esta etiqueta por si sola • ENCTYPE: Nos permite especificar la codificación que
no es representada por el navegador, esto es, el usuario no llevarán los datos que contenga el formulario:
verá nada en su pantalla, sino que simplemente le indica que • t e x t / p l a i n : Los caracteres que incluya cada campo
a continuación habrá elementos de formulario (campos), los del form ulario serán enviados tal cual. Debido a
cuales sí son mostrados al usuario para que pueda introducir ello, si el formulario incluye el envío de ficheros, su
la información pertinente. contenido no será tratado adecuadamente y tampoco
Como todo elemento HTML, esta etiqueta dispone de una podrá ser recuperado en la página destino (atributo
serie de atributos que nos perm itirán amoldarla a nuestras ACTION). Este valor se toma por defecto si no se
necesidades: especifica este atributo.
• m u l t i p a r t / f o r m - d a t a : Los caracteres también
• ID: Con él podremos dar al formulario un identificador
son enviados sin modificar, pero sí perm ite incluir
único como elemento de la página. ficheros junto con el formulario.
• ÑAME: Nos permite asignarle un nombre al formulario
• a p p lic a tio n / x -w w w -fo r m -u r le n c o d e d : En este
para poder identificarlo dentro de la página. caso, los caracteres de cada cam po del formulario
• ACTION: Aquí debem os indicar a qué URL se van a serán codificados antes de ser enviados. Dicha codi­
enviar los datos que recoja el formulario. Por lo general, ficación consiste en sustituir los espacios por signos
suele ser una página con un lenguaje de servidor, como
de suma (+) y convertir los caracteres especiales a un
PHP o ASP, que se encargará de recopilar los datos y valor hexadecimal.
tratarlos en el servidor Web.
• METHOD: Con este atributo podremos definir de qué ma­ No es obligatorio definir todos los atributos que acabamos
nera se van a enviar los datos. Existen dos métodos: de presentar, por lo que aquellos que no estén presentes to­
• g e t : Todos los valores del formulario se enviarán m arán su valor por defecto (si tuvieran). Por lo general, los
dentro del URL detrás del carácter de interrogación campos ID, ÑAME y ACTION se deben especificar para tener
(?), formando la cadena de consulta o Cjuery string. unos datos mínimos.
Este m étodo no es aconsejable para tratar inform a­ Veamos algunos ejemplos, con funcionalidades inventadas,
ción confidencial, ya que todos los datos quedan a de cómo se incluiría un formulario en nuestra página Web:
la vista del usuario en la barra de direcciones. <HTML>
• p o s t : En este caso los datos van encapsulados en la <BODY>
petición HTTP al servidor W eb haciendo que todos <H3>Formulario para dar de alta un usuario</H3>
los datos estén ocultos de cara al usuario, lo cual <FORM ID="forraulariol" NAME="formRegistro"
ACTION="registrar.php" METHOD="get">
le convierte en el candidato perfecto para manejar </FORM>
información sensible como contraseñas o números <H3>Formulario para subir ficheros al servidor</H3>
de identificación. <FORM ID="formulario2" NAME="formFicheros"
• TARGET: Con esto indicamos en qué ventana se va a abrir ACTION="guardar_ficheros.php" METHOD="post"
el URL que recogerá el formulario (atributo ACTION). ENCTYPE="multipart/form-data">
</FORM>
Los posibles valores son:
• b la n k : El URL se abrirá en una ventana nueva. <H3>Formulario para confirmar una compra</H3>
• _ s e l f : En este caso se abrirá la ventana o marco <FORM ID="formulario3" NAME="formCompra"
ACTION="confirmar_compra.php" TARGET="_blank">
actual. Es el valor por defecto. </FORM>
• p a r e n t : La ventana que contenga los marcos será </BODY>
la encargada de cargar el URL. Si no hubiera marcos </HTML>
entonces se abrirá en la ventana actual.
Como ya hemos dicho, si cargamos una página con este có­
to p : El URL será abierto en la ventana de nivel
digo no se verá nada en la pantalla ni serán de utilidad puesto
inm ediatamente superior o, en caso de no haberla,
que deberem os incluir adem ás alguno de los cam pos que
en la actual.
203
vam os a ver a continuación. En los próxim os ejemplos vamos la pantalla. A la hora de trabajar con este cam po, el
a usar estos mismos formularios para ir com pletándolos y, texto se recupera tal y como se escribió.
finalmente, aplicarles controles mediante JavaScript. • h id d e n : Crea una caja de texto que estará oculta a la
vista del usuario, de modo que no estará represen­
tada en la pantalla. Su utilidad reside en transportar
9.1.2. Campos de entrada de datos valores temporales o de estado.
Estos campos son unos de los más importantes dentro de • f i l e : N os m ostrará un cuadro preparado para
un formulario, ya que nos permiten tomar datos que el usuario poder buscar un fichero en el ordenador del usuario
escribe directamente "de su puño y letra . El navegador^ os y adjuntarlo al formulario.
representa como un cuadro de texto (de distintos tamaños) • MAXLENGTH: Nos permite limitar el número máximo de
y seguro que los ha visto más de una vez en m uchas de las caracteres que se pueden escribir en un cuadro de texto.
páginas que visita frecuentem ente, com o el correo W eb, la • SIZE: Con este atributo establecem os el núm ero de
cuenta del banco o un foro. Los campos de entrada de datos caracteres que se verán al mismo tiempo en el cuadro de
van identificados por las etiquetas <INPUT> y <TEXTAREA>. texto. No impone un límite en la longitud del texto sino
Cada una de ellas tiene una serie de atributos, aunque tienen únicamente en la cantidad de caracteres que podremos
en común los siguientes: ver en nuestra pantalla dentro de ese cuadro. Si le resulta
más fácil, se podría definir como el ancho que tendrá el
• ÑAME: Como ocurre en todos los elementos HTML, este cuadro. Obviamente este valor no tiene efecto sobre los
atributo nos permite asignar un nombre al campo para campos ocultos (h id d en ).
que pueda ser identificado. • VALUE: Este atributo representa el texto que contiene el
• DI SABLED: Nos permite desactivar un campo de forma cuadro correspondiente. En caso de tener un campo de
que no pueda ser utilizado por el usuario. La inform a­ tipo f i l e este atributo no tiene utilidad.
ción que contenga será visible, pero el cam po aparecerá Finalmente veremos los atributos que podremos aplicar
sombreado. No necesita ir acom pañado de un valor únicamente en los campos <TEXTAREA>, que no son más
como, por ejemplo, el atributo ÑAME sino que el campo se que unos cuadros de texto en los que es posible escribir
desactivará simplemente con tener este atributo presente varias líneas:
en su etiqueta HTML. • COLS, ROWS: Serían el equivalente al atributo SIZE de
• READONLY: Es similar a DISABLED, salvo que no som­ las cajas simples. Con ellos podremos establecer, res­
brea el campo totalmente. pectivamente, el ancho y el alto que tendrá esta caja de
texto, siendo ROWS el número de filas y COLS el número
Nota: Los campos con él atributo DISABLED presente no de caracteres visibles por fila.
serán enviados junto con el resto del form ulario. Si desea
enviar un campo que no deba ser manipulado por el usual io, Nota: Si no se especifica un tamaño para los cuadros de texto
Utilice READONLY.________ (atributos S IZ E , COLS o ROWS), cada navegador asignará
unos valores por defecto.
Veamos ahora los atributos propios de la etiqueta <INPUT>,
que en este caso representa las cajas de texto simples. Veamos ahora cómo insertar este tipo de campos en nues­
• TYPE: Posibilita definir el tipo de la caja de texto m e­ tros formularios de ejemplo.
diante uno de estos valores: <HTML>
• t e x t : Hace que se muestre una caja para introducir <BODY>
texto genérico. <H3>Formulario para dar de alta un usuario</H3>
• p a ssw o rd : M uestra una caja de texto con la pecu <FORM ID="formulariol" NAME="foriaRegistro"
ACTION="regi strar.php" METHOD="get">
liaridad de que los caracteres escritos se representan
Tu nombre: «CINPUT TYPE="text" ID="entradal"
como asteriscos (*) para que no queden visibles en

204 205
NAME="nombreUsuario" MAXLENGTH-"8" /> Formulario para confirmar mía compra
(Máximo 8 c a r a c t e r e s ) <BR />
Tu c o n t r a s e ñ a : CINPUT T Y P E = " p a s s w o r d " ID- e n t r a d a /
Tu usuario:
NAME="clave" / X B R />
Tu email: <INPUT TYPE="text" ID="entrada3" Importe total: ¡54.75 j euros
NñME="email" SIZE=”40" />
</FORM> Figura 9.3. Formulario de compra.

Fonnulario para dar de alta iin usuario


9.1.3.Campos de selección de datos
(Máximo 8 caracteres)
Tu nombre: | Aparte de la entrada de datos mediante teclado, el usuario
Tu contraseña: f tam bién podrá aportar inform ación escogiendo un valor
Tu email: 1 -------------------- 1 dentro de una serie de opciones que se le ofrece. Para incluir
este tipo de cam pos en un form ulario deben utilizarse las
Figura 9.1. Formulario de registro.
etiquetas <INPUT> o <SELECT>. La prim era ya la conoce,
aunque en este caso hay que definirla de form a que no co­
<H3>Formulario para subir ficheros al servidor</H3>
rresponda con una caja de texto, y la segunda m uestra una
<FORM ID="formulario2" NAME="formFicheros'
lista desplegable o drop-dozvn para poder seleccionar un valor
ACTION="gua rda r_fi che ro s.php" METHOD="post"
ENCTYPE="multipart/form-data">
de esa lista.
Fichero: <INPÜT TYPE="file" I D = " e n t r a d a 4 " Ambas etiquetas tienen una serie de atributos comunes:
NAME="fichero" / X B R />
Descripción: <TEXTAREA ID="entrada5" N A M E -’ descripción • ÑAME: Representa el nombre con el que se identifica el
COLS="40" R0WS="3"X/TEXTAREA> campo.
</FORM> • DI SABLED: Permite deshabilitar el campo, de forma que
el usuario no podrá interactuar con él.
Formulario para subir ficheros al servidor
La etiqueta <INPUT> representa en este caso unos campos
¡ Examinar... J o datos que son opcionales en nuestro formulario (por ejemplo,
Fichero:
si se desea recibir publicidad en el email), aunque también se
utiliza para poder elegir una opción entre varias disponibles
Descripción:
(puntuación entre 1 y 10 en un test, por ejemplo). No almacenan
___________ _________________ un valor escrito por el usuario sino que únicamente pueden
Figura 9.2. Formulario de ficheros. estar seleccionados o no. Cuando la etiqueta <INPUT> adopta
esta funcionalidad dispone de tres atributos:
<H3>Formulario para confirmar una compra</H > • TYPE: Nos permite definir el tipo del elemento con uno
<FORM ID=”formulario3" NAME="formCompra de estos valores:
ACTION="confirmar_compra.php" TARGET- _blank >
<i— campo oculto con la fase del proceso de compra — >
• r a d i o : M ostrará un botón de radio, es decir, un
<INPUT TYPE="hidden" ID="entrada6" ÑAME— "fase" círculo vacío cuando no está seleccionado y relleno
VALUE="confirmacion"> t cuando lo está. Se utilizan cuando querem os que
Tu usuario: CINPUT TYPE="text" ID="entrada7 el usuario elija un único valor entre una serie de
NAME="usuario" MAXLENGTH=" 8 " X B R /> opciones (puntuación entre 1 y 10).
Importe total: <INPUT TYPE="text" ID="entrada8 • c h e c k b o x : Este tipo representa una caja de valida­
NAME="importe" SIZE="10" VALÜE="54,75" READONLY> euros
ción que estará vacía cuando no esté seleccionada, y
</FORM> rellena con un aspa cuando sí lo esté. Sirven para que
</BODY>
el usuario pueda activar o desactivar las opciones
</HTML>

207
206
que representen, como por ejem plo si desea recibir • SELECTED: Hace que la opción aparezca como seleccio­
un boletín sem anal en su correo electrónico. nada en la lista desde un principio. Si el usuario cambia
• CHECKED: Hace que el elemento esté seleccionado desde la selección se anula el efecto de este atributo.
un principio. Si el usuario lo deselecciona, este atributo
Veamos ahora cómo incluir estos nuevos campos a nues­
no tendrá efecto a la hora de mandar el formulario. Al tros formularios.
igual que los atributos DISABLED o READONLY, no es
necesario un valor a continuación. <HTML>
<BODY>
• VALUE: Representa el valor que tiene asignado el campo.
<H3>Formulario para dar de alta un usuario</H3>
Este valor no será mostrado junto al elemento de selec­
<FORM ID="formulariol" NAME="formRegistro"
ción sino que será el valor que se envíe con el formulario, ACTION="registrar.php" METHOD="get">
siempre y cuando el campo esté seleccionado. Sin em ­ Tu nombre: <INPÜT TYPE="text" ID="entradal"
bargo, si el elemento no está seleccionado el valor que NAME="nombreUsuario" MñXLENGTH="8" /> (Máximo 8
enviaremos será una cadena vacía. caracteres)<BR />
Por otro lado, la etiqueta <SELECT> mostrará una lista Tu contraseña: <INPÜT TYPE="password" ID="entrada2"
NAME="clave" /><BR />
desplegable con varias opciones entre las cuales el
Tu email: CINPUT TYPE="text" ID="entrada3" NAME="email"
usuario podrá seleccionar una o varias. Un ejemplo de su SIZE="40,T />
uso sería que mostrase al usuario una lista de los meses Tu pais: <SELECT ID="seleccionl" NAME="pais">
del año haciendo que elija aquel que corresponda con <OPTION ID="opcionl" VALUE="AND">Andorra</OPTION>
su fecha de nacimiento. Esta etiqueta tam bién dispone <OPTION ID="opcion2" VALUE="ESP"
de atributos adicionales: SELECTED>España</OPTION>
• SIZE: Nos permite definir cuántos elementos de la lista <OPTION ID="opcion3" VALUE="POR" >Portugal
</OPTION>
se mostrarán al mismo tiempo. El valor por defecto es 1, </SELECT>
y el elemento se representa como una lista desplegable. Si </FORM>
este atributo tiene un valor superior, entonces se mostrará
como un cuadro de texto con una barra de desplazamiento
vertical tomando una apariencia similar a un TEXTAREA. Fonnulario para «lar (le alta im usuario
• MULTIPLE: Indica que se podrá seleccionar más de un
Tu nombre: |(Máximo 8 caracteres)
valor de la lista. Para ello, hay que mantener presionado
el botón Control mientras se hace clic sobre las opciones Tu contraseña: |
que se quiera. Este atributo no necesita un valor aso­ Tu email: 1
ciado, de modo que con estar presente ya se activa esta Tupáis: |España ¡vil
funcionalidad.
Figura 9.4. Formulario de registro.
Para definir cada una de las opciones, que contienen las
listas desplegables, hay que usar otra etiqueta, <OPTION>,
<H3>Formulario para subir ficheros al servidor</H3>
que contiene los atributos com unes de <SELECT> (ÑAME y
<FORM ID="formulario2" NAME="formFicheros"
DISABLED) junto con otros dos: ACTION="guardar_ficheros.php" METHOD="post"
• VALUE: Representa el valor que tiene asignada la opción. ENCTYPE="multipart/form-data">
Fichero: <INPÜT TYPE="file" ID="entrada4"
Este valor no se muestra junto al elemento, sino que es
NAME="fichero" / X B R />
enviando dentro del formulario. Para asociarle un texto
Descripción: -CTEXTAREA ID="entrada5" NAME="descripcion"
visible al usuario sólo hay que escribirlo al lado de la COLS="40" ROWS— "3"X / T E X T A R E A X B R />
etiqueta <OPTION>, y no tiene por qué coincidir con el CINPUT TYPE="checkbox" ID="seleccion2"
valor que se va a mandar. Podemos tener una opción NAME="comprimir" /> Comprimir en ZIP
con el valor 1 y el texto "Enero". </FORM>

208 209
• ÑAME: Indica el nombre del campo, mediante el cual es
Formulario para subir ficheros al servidor
posible identificarlo.
| Examinar... ]
• TYPE: N os perm ite especificar el tipo de botón que
Fichero:
vamos a incluir en el formulario:
• b u t t o n : Describe un botón de uso genérico, al que
Descripción: podremos asignar la acción que debe realizar al ser
pulsado, que normalmente se trata de una función
□ Comprimir en ZIP JavaScript.
• submit: Es un tipo especial de botón que envía
Figura 9.5. Formulario de ficheros. automáticamente toda la información del formulario
cuando es pulsado.
<H3>Formulario para confirmar una compra</H3> • reset: Se trata de otro botón especial que, cuando
<FORM ID="formulario3" NAME="formCompra" es pulsado, vuelve a dejar todo el formulario tal y
ACTION="confirmar_compra.php" TARGET="_blank"> como estaba al cargar la página, borrando toda la
< i— Campo oculto con la fase del proceso de compra -->
inform ación que hubiese introducido el usuario y
CINPUT TYPE="hidden" ID="entrada6" NAME="fase"
eliminando sus selecciones.
VALUE="confirmacion">
Tu usuario: CINPÜT TYPE="text" ID="entrada7" • VALUE: Al contrario que otros campos, el valor de este
NAME-"usuario” MAXLENGTH="8"X B R /> atributo corresponde con el texto que se muestra dentro
Importe total: CINPUT TYPE="text" ID="entrada8" del botón para así informar al usuario de la función que
NAME="importe" SIZE="10" VALUE="54,75" READ0NLY> desempeña. Por ejemplo, se puede crear un botón con
euros<BR /> valor "Registrarse" o "Calcular". Si no se añade este atri­
Pago: CINPUT TYPE="radio" ID="seleccion3" NAME="pago"
buto, el texto mostrado por defecto es una cadena vacía,
VALUE="Tarjeta"> Tarjeta VISA/MASTERCARD <INPUT
TYPE="radio" ID="seleccion4" NAME="pago" VALUE="Paypal > excepto para los de tipo submit que será "Enviar con­
Paypal <INPUT TYPE="radio" ID="seleccion5" NAME="pago" sulta", y para el tipo reset que mostrará "Reestablecer".
VALUE="Efectivo" CHECKED> En efectivo Estos textos por defecto dependen también del idioma
</FORM> del sistema y pueden variar de un navegador a otro,
</BODY> pero serán similares.
C/HTML>
Finalm ente, podremos com pletar nuestros tres form ula­
Formulario para confirmar ima compra rios de ejemplo, añadiendo los botones correspondientes que
determinarán las acciones que se llevarán a cabo en cada uno
de ellos.
Tu usuario: [________ ________]
Importe total: [54.75 [ euros <HTML>
Pago: O Tarjeta VISA/M ASTERCAKD O Paypal ® En efectivo
<B0DY>
<H3>Formulario para dar de alta un usuario</H3>
Figura 9.6. Formulario de compra. <F0RM ID="formulariol" NAME="formRegistro"
ACTI0N="registrar.php" METHOD="get">
Tu nombre: CINPUT TYPE="text" ID="entradal"
9.1.4. Botones NAME="nombreUsuario" MAXLENGTH="8" /> (Máximo 8
caracteres)CBR />
Por último verem os otros elementos de gran importancia Tu contraseña: CINPUT TYPE="password" ID="entrada2"
NAME="clave" />CBR />
dentro de un form ulario: los botones. Con ellos podremos
Tu email: CINPÜT TYPE="text” ID="entrada3" NAME="email"
ejecutar una serie de operaciones con los datos introducidos SIZE="40" />
en el formulario. Todos los botones se definen, de nuevo, con Tu país: CSELECT ID="seleccionl" NAME="pais">
la etiqueta <INPUT> y los siguientes atributos:

210 211
COPTION ID="opcionl" VALUE="AND">Andorra</OPTION> <H3>Formulario para confirmar una compra</H3>
<OPTION ID="opcion2" VALUE="ESP" SELECTED>España</ <FORM ID="formulario3" NAME="formCompra"
OPTION> ACTION="confirmar_compra.php" TARGET="_blank">
COPTION ID="opcion3" VALUE="POR" >PortugalC/ <! Campo oculto con la fase del proceso de compra — >
OPTION> <INPUT TYPE="hidden" ID="entrada6" NAME="fase"
</SELECTXBR /><BR /> VALUE="confirmacion">
CINPUT TYPE="reset" ID="botonl" NAME="limpiar" /> Tu usuario: CINPUT TYPE="text" ID="entrada7"
< INPUT TYPE="submit" ID="boton2" NAME="enviar" /> NAME="usuario" MAXLENGTH="8"X B R />
</FORM> Importe total: CINPUT TYPE="text" ID="entrada8"
NAME="importe" SIZE="10" VALUE="54,75" READONLY>
euros<BR />
Pago: -CINPUT TYPE="radio" ID="seleccion3" NAME="pago"
VALUE="Tarjeta"> Tarjeta VISA/MASTERCARD <INPUT
TYPE="radio" ID="seleccion4" NAME="pago" VALUE="Paypal">
Paypal <INPUT TYPE="radio" XD="seleccion5" NAME="pago"
VALUE="Efectivo" CHECKED> En efectivo<BR / X B R />
<INPUT TYPE="button" ID="boton5” NAME="confirmar"
VALUE="Confirmar y seguir >" />
</FORM>
</BODY>
</HTML>
Figura 9.7. Formulario de registro.

<H3>Formulario para subir ficheros al servidor</H3> Foimiilaiio pai'a coiifinnar ima compra
CFORM ID="formulario2" NAME="formFicheros"
ACTION="guardar_ficheros.php" METH0D="post" Tu usuario: j_________ |
ENCTYPE="multipart/form-data"> Importe total: [54,75 |euros
Fichero: CINPUT TYPE="file" ID="entrada4" NAME="fichero"
Pago: O Tarjeta VISA/M ASTERCARD O Paypal ® En efectivo
/ X B R />
Descripción: CTEXTAREA ID="entrada5" NAME="descripcion" | Confirmar y seguir» ]
COLS="40" ROWS = "3"></TEXTAREAXBR />
<INPUT TYPE="checkbox" ID="seleccion2" NAME="comprimir" Figura 9.9. Formulario de compra.
/> Comprimir en ZIP<BR />
<INPUT TYPE="reset" ID="boton3" NAME="limpiar"
VALUE="Cambiar fichero"/> <INPUT TYPE="submit" 9.1.5. Resumen de tipos de elementos <INPUT>
ID="boton4" NAME="enviar" VALUE="Subir fichero"/>
</FORM> Para que no tenga que repasar de arriba abajo este capí­
tulo en busca de los posibles valores del atributo T Y P E para
Fonmilaiio pni si subii' ficheros al servidor los campos < I N P U T >, le incluyo a continuación una pequeña
tabla resum en que espero le sea de ayuda.
Fichero: Examinar,.-
Tabla 9.1. Valores del atributo TYPE en campos <INPUT>.
Descripción:
Elemento Valores TYPE

□ Comprimir en ZIP Entrada de datos text, password, file, hidden


Cambiar fichero | [ Subir fichero Selección de datos radio, checkbox
Figura 9.8. Formulario de ficheros. Botones button, submit, reset

212 213
9.2. Formularios en JavaScript <SCRIPT TYPE="text/javascript">
// Acceso a un campo
var primerCampo = document.forms[0].
Una vez que ya conocemos los formularios HTM L y todo elements[0 ];
lo que pueden incluir vamos con lo que nos interesa: cómo var unCampo = document.forms[0].
elements["nombre"];
acceder y trabajar con esos formularios desde nuestro código
</SCRIPT>
JavaScript.
También se puede usar directamente los nombres del
formulario y/o el campo:
9.2.1. Formulario
<SCRIPT TYPE="text/javascript">
Como dijimos en el capítulo dedicado al DOM, el objeto // Acceso a un campo
docu m ent nos perm ite un acceso directo a todos los form u­ var primerCampo = document.formRegistro.
larios de la página a través de la colección fo rm s . De este elements[0];
modo, acceder a un formulario resulta tan sencillo como usar var unCampo = document.forms[0].nombreüsuario;
var otroCampo = document.formRegistro.clave;
esta colección j un to con ion índice o el nombre de uno de los </SCRIPT>
formularios existentes (atributo ÑAME).
<SCRIPT TYPE="text/j avascript">
A través de esta colección de elem entos podremos conocer
// Acceso a un formulario el número de campos que contiene cada formulario:
var miForm = document.forms[0];
<SCRIPT TYPE="text/javascript">
var miForm = document.forms["formRegistro"];
// Cantidad de campos en cada formulario
</SCRIPT> for(var i=0; i<document.forms.length; i++) {
Aunque esta es la forma más correcta, también es posible alert("El formulario " + i + " tiene ” + document.
acceder directamente con el nombre de la siguiente manera: forms[i].elements.length + " campos");
)
<SCRIPT TYPE=" text/javascript"> </SCRIPT>
// Acceso a un formulario con el nombre
var miForm — document.formRegistro;
Nota: El tercer form ulario contiene 7 campos puesto que
</SCRIPT>
también se contabilizan los campos ocultos ( h id d e n ) .
Tomando como base los tres formularios que hemos defi­
nido en el apartado anterior, veam os cómo obtener el número ........ .....................
de formularios que contiene la página: La página en http://localhos1 dice: |X |

<SCRIPT TYPE="text/javascript"> | ^/j El formulario 0 tiene 6 campos

// Cantidad de formularios en la página


alert("Hay " + document.forms.length + " formularios La página en http://localhost dice: |X |
en esta página"); // Hay 3 formularios
El formulario 1 tiene 5 campos
</SCRIPT> ¿h 1
A continuación verem os todos los elementos a los que po­ La página en http://localhost dice: |X

demos acceder dentro de un formulario. ^j ^ El formulario 2 tiene 7 campos i

Colecciones de objetos
| Aceptar | ’
• e l e m e n ts : Se trata de una arraij con todos y cada uno
de los campos que componen el formulario. Se puede ac­ Figura 9.10. Información del número de campos de los distintos
ceder a cada campo m ediante un índice o su nombre. formularios.

214 215
Propiedades • reset () :D eja el formulario en blanco, tal ycom ocsl.ikt
al cargar la página. Realiza la misma acción que un botón
Básicamente podrem os obtener y m odificar todos los atri­ de tipo reset.
butos HTM L del formulario
A modo de ejemplo de estos métodos, crearemos un pe­
• id : Representa el identificador del formulario (atributo
queño script que nos lim pie el primer formulario pasados 10
ID). segundos. Para ver su efecto escriba algo en alguno de sus
• ñame, action, method, target, enctype: Representan
campos antes de que pase ese tiempo.
cada uno de los atributos que hemos descrito en el apar­
tado anterior. <SCRIPT TYPE="text/javascript">
• length: Nos dirá el número de campos que tiene el // Función que limpia un formulario
function limpiarForm(formulario) {
formulario. Es lo mismo que elements .length. formulario.reset();
Gracias a estas propiedades podremos obtener algo más de )
información de los formularios para usarlo en nuestros scripts: // Inicialización de temporizador
setTimeout("limpiarForm(document.forms[0])", 10000) ;
<SCRIPT TYPE="text/javascript"> </SCRIPT>
var formulario;
// Cantidad de campos en cada formulario
for(var i=0; i<document.forms.length; i++) { 9.2.2. Campos de entrada de datos
formulario = document.forms[i];
alert("El formulario " + i + " (" + formulario JavaScript también nos permite acceder a estos campos para
ñame + ") tiene " + formulario.length + " campos
manejarlos desde nuestros scripts.
que va a enviar al URL " + formulario.action +
" utilizando el método " + formulario.method);
Propiedades
}
</SCRIPT> Al igual que los elementos HTM L que representan estos
campos, hay una serie de propiedades comunes para todos
ellos:
• id: Representa el identificador del formulario (atributo
ID).
• disabled, ñame, readOnly, type, valué: Devuelven
el valor del atributo HTM L correspondiente.
• form : Nos indica el objeto de formulario donde está
contenido el campo actual.
Las cajas de texto, definidas con <INPUT>, tienen además
estas propiedades:
• maxLength: Nos permite obtener y modificar la lon­
gitud máxima del campo. Si no se ha especificado esta
Figura 9.11. Información de los distintos formularios. propiedad, se devuelve -1.
• size: Devuelve el número de caracteres visibles en el
M étodos campo. También podremos cambiarlo directamente en
nuestro código.
• s ubmi t ( ) : Envía el formulario con toda la información
que haya introducido el usuario en él. Equivale a un Como no podía ser de otra manera, los <TEXTAREA> tam ­
botón de tipo su b m it. bién tienen algunas propiedades suyas:

216 217
• c o i s , ro w s: Nos dejan obtener o modificar el ancho o el [Aplicación JavaScript]
alto del cuadro de texto. Si alguna de estas propiedades
El campo nombreUsuario está en d formularlo formRegistro y sus propiedades son:
no ha sido definida, se obtiene un valor -1. - ID: entradal
-Nombre: nombreUsuario
- Tipo: text
Veam os cómo usar todas estas propiedades con nuestro -Valor:
- Deshabilitado: false
ejemplo, tomando algunos campos cuya propiedad ty p e sea -Sólo lectura: false
- Longitud máxima: 8
de uno de estos tipos. -Ancho: 0

<SCRIPT TYPE="text/javascript"> | Aceptar ¡


var formulariol = document -forms [0] ;
var formulario2 = document.forms[1];
Figura 9.12. Información del campo nombreUsuario.
var formulario3 = document.forms[21;
// Muestra las propiedades de un campo de entrada de datos
function mostrarPropiedades(campo) { [Aplicación JavaScript] (x"|
var datos = "El campo " + campo.ñame + " está
El campo clave está en el formulario formRegistro y sus propiedades son:
en el formulario " + campo.form.ñame + y -ID: entrada2
sus propiedades son:\n"; -Nombre: clave
- Tipo: password
datos += "\t- ID: " + campo, id + "\n"; -Valor:
-Deshabilitado: false
datos += "\t— Nombre: " + campo.ñame + "\n"; - Soto lectura: false
datos += "\t- Tipo: " + campo.type + "\n"; -Longitud máxima: -1
- Ancho: 0
datos += "\t- Valor: " + campo.valué + "\n”;
datos += "\t- Deshabilitado: " + c a m p o .disabled + [ Aceptar j¡
"\n";
datos += "\t- Sólo lectura: " + campo.readOnly + \n ;
Figura 9.13. Información del campo clave.
// Añadir los campos específicos del tipo de campo
if (campo.type == "textarea") {
datos += "\t- Ancho: " + campo.cois + "\n"; [Aplicación JavaScript]
datos += "\t- Alto: " + campo.rows+ "\n";
El campo fichero está en el formulario formFicheros y sus propiedades son:
} else { - ID: entrada4
-Nombre: fichero
datos += "\t- Longitud máxima: " + campo. - Tipo: file
maxLength + "\n"; - Valor:
- Deshabilitado: false
datos += "\t- Ancho: " + campo.size + "\n"; -Sólo lectura: false
-Longftud máxima: -1
} -Ancho: 0
// Mostrar las propiedades
alert(datos);
}
// Mostramos algunos campos Figura 9.14. Información del campo fichero.
mostrarPropiedades(formulariol.
elements["nombreUsuario"]);
mostrarPropiedades (formulariol .elements ["clave"] )^; [Aplicación JavaScript] |X ¡ I
mostrarPropiedades(formulario2.elements["fichero"]);
El campo descripción está en el formulario formFicheros y sus propiedades son:
mostrarPropiedades(formulario2.elements["descripción"]); -ID: entrada5
-Nombre: descripción
mostrarPropiedades(formulario3.elements["fase"]); -Tipo: textarea
mostrarPropiedades(formulario3.elements["importe"]); - Valor:
- Deshabilitado: false
</SCRIPT> - Sólo lectura: false
-Ancho: 40
-Alto; 3

Truco: A través de JavaScript, la propiedad t y p e no es | Aceptar


exclusiva de los campos <INPUT>, sino que nos dice el tipo
de cualquier campo. _______ _ _ _ _______ ____ Figura 9.15. Información del campo descripción.

218 219
[A plicación Ja v a S c rip t]
Con un sencillo código podremos hacer que el rm v n ,
sitúe en cualquiera de las cajas (establecer el foco) n.ul.i iim ,
. B campo fase está en el formulario formCompra y sus propiedades son:
. I . -ID:entrada6
cargarse la página. De este modo forzamos un poco n «pie ■ m
-Nombre: fase sea el primer campo que rellene usuario cuando eni|'iri < .i
- Tipo: hidden
-Valor: confirmación escribir.
-Deshabilitado: false
- Sólo lectura: false
-Longitud máxima: -1 <SCRIPT TYPE="text/javascript">
-Ancho: 0 var formulariol = document.forms[0];
¡ Aceptar | // Ponemos el foco en el email
formulariol.elements["email"].focus();
</SCRIPT>
Figura 9.16. Información del campo fase.
Mediante este otro script, seleccionaremos todo el texto mu*
[Aplicación Ja v a S c rip t] haya en el <TEXTAREA> una vez hayan pasado 10 segundos
desde que se cargó la página. Si escribimos algo en él antes de
El campo importe está en el formularlo formCompra y sus propiedades son:
-ID: entrada8 que ocurra, veremos el efecto.
-Nombre: importe
-Tipo: text <SCRIPT TYPE="text/j avascript">
- Valor: 54;75
-Deshabitada: false // Función que selecciona un campo
-Sólo lectura: true
- Longitud máxima: -1
function seleccionarCampo(campo) {
-Ancho: 10 campo, select () ;
| Aceptar ¡j }
// Inicialización de temporizador
setTimeout("seleccionarCampo(document.forms[1].
Figura 9.17. Información del campo importe. elements['descripción'])", 10000);
</SCRIPT>
Recuerde que también es válido acceder a un campo o for­
mulario directamente a través de su nombre:
Nota: A quí se han utilizado las comillas simples para indicar
<SCRIPT TYPE="text/javascript"> el nombre del campo simplemente por comodidad y evitar
// Mostramos algunos campos poner la comilla doble con el carácter de escape. Sería igual­
mostrarPropiedades(formulariol.nombreUsuario);
mostrarPropiedades(document.formRegistro.clave) ;
mente válido escribirlo como [ \ " d e s c r i p c i ó n \ "].
mostrarPropiedades(formulario2.fichero);
mostrarPropiedades(formulario2.descripción);
mostrarPropiedades(formulario3.fase);
9.2.3. Campos de selección de datos
mostrarPropiedades(formulario3.importe);
</SCRIPT>
Estos campos pueden ser controlados directamente desde
el código, lo cual nos aportará una gran flexibilidad a la hora
Se habrá dado cuenta de que hemos distinguido los dife­ de validar nuestros formularios.
rentes tipos de campos a través de la propiedad ty p e . En el
apartado 9.2.5 podrá encontrar una lista de todos los valores Colecciones de objetos
posibles de esta propiedad.
Veam os ahora los métodos disponibles para los campos de Como viene ocurriendo con algunos objetos, aquí tenemos
entrada de datos. uno más que contiene a su vez un conjunto de otros objetos. Se
trata de una colección que representa los elementos <OPTION>
M étodos que, obviamente, sólo estará presente en los <SELECT>.

• f o c u s ( ) , b l u r ( ) : Establece o retira el foco de la caja. • o p t i o n s : Contiene un array todas las opciones que
• s e l e c t ( ): Selecciona todo el texto que esté escrito dentro m uestra la lista desplegable. Ú nicam ente se puede
de la caja de texto. acceder a cada opción a través de un índice.

220 221
<SCRIPT TYPE="text/javascript"> • size: Nos devuelve el valor del atributo I : ,K, tiiir
// Acceso a la colección de opciones de una viene a ser el número de opciones visibles <il mismo
// lista desplegable tiempo en la lista desplegable.
var campoSelect = document.forms[0].elements[3],
• length: Nos indica el número de opciones de l.is ■pic
var unaOpcion = c a m p o S e l e c t .o p t i o n s [0];
dispone. Este valor equivale a la longitud de su co lea k >ii
</SCRIPT> de datos, es decir, options .length.
Además de obtener cada opción por separado, podremos • selectedlndex: Nos permite obtener o establecer la
saber el número de todas ellas, ya que se trata de un a r r a y . opción que está seleccionada, a través de un índice que
<SCRIPT TYPE=”text/javascript"> corresponde a su posición dentro de la lista. Iil índice 0
// Cantidad de opciones en el campo select representa la primera opción en el orden que están de­
var campoSelect = d o c u m e n t . forms[0].elements[3]; finidas en la página HTML. La última posición se puede
alert("El campo select " + c a m p o S e l e c t .ñame + calcular restando 1 a su longitud (número de opciones).
" tiene " + campoSelect.options.length + opciones Esta propiedad toma el valor especial -1 cuando no hay
// Mostrará 3 opciones ninguna opción seleccionada.
</SCRIPT>
Por último, no nos olvidamos de los elementos <OPTION>,
propiedades que son muy envidiosos y también tienen sus propiedades
aparte:
Todos los elem entos HTML de selección que tenemos a
nuestra disposición (<INPUT>, <SELECT> y <OPTION>) dis­ • selected: Nos permite saber o fijar cuándo la opción
ponen de unas cuantas propiedades comunes. estará seleccionada.
• id : Equivale al identificador del cam po (atributo ID). • text: Obtiene el texto que se encuentra junto a la eti­
• ñame, ty p e: Representan el nombre y el tipo del elemen o queta <OPTION> y también nos deja modificarlo.
(atributos ÑAME y TYPE), excepto para los <OPTION>, • index: Devuelve la posición que ocupa la opción dentro
de la lista desplegable.
que no disponen de estos atributos.
• v a lu é - Nos devuelve el valor que tenga asociado el A continuación dispone de un script que mostrará todas
campo en su atributo VALUE. En el caso de los <SELECT> estas propiedades:
nos devolverá el valor de la opción que este seleccio
<SCRIPT TYPE="text/javascript">
var fonmilariol = document.forms[0];
• d i s a b l e d : N os perm ite h abilitar o deshabilitar el var formulario2 = document.forms[1];
campo, m odificando el atributo DISABLED. var formulario3 = document.forms[2];
. f orm: Nos devuelve el objeto de formulario en el que // Muestra las propiedades de un campo de selección
// de datos
se encuentra el campo.
function mostrarPropiedades(campo) {
Adicionalmente, los dos tipos de elementos < I N P U T > que var datos = "El campo " + campo.ñame +
pueden existir en un formulario ( r a d io y c h e c k b o x ) tienen está en el formulario " + campo.form.ñame + " y
sus propiedades son:\n";
estas propiedades:
datos += "\t- ID: " + campo.id + "\n";
• c h e c k e d : Perm ite saber y establecer cuándo está selec­ // Los option no tienen estas propiedades
cionado el campo. if (typeof(campo.type) != "undefined") {
datos += "\t- Nombre: " + campo.ñame + "\n";
Por otro lado, las listas desplegables (<SELECT>) también datos += "\t— Tipo: " + campo.type + "\n";
nos ofrecen un puñado más de propiedades, que ademas son }
bastante útiles: datos += "\t- Deshabilitado: " + campo.disabled +
"\n";
• m ú l t i p l e : Nos permite conocer y establecer cuándo la // Añadir los campos específicos del tipo de campo
lista admite selección múltiple.

223
if (campo.type = "select-one" II campo.type
[Aplicación JavaScrip t]
"select-multiple") {
datos += "\t- Opciones visibles: " + campo.size y El campo undefined esté en el formulario formRegistro y sus propiedades son:
-ID: opdonl
+ "\n"; -Deshabitado: false
datos += "\t- Opciones totales: " + campo.length -Texto: Andorra
-Posición: 0
+ °\n"; -Seleccionado: false
datos += "\t- Múltiple: " + campo.múltiple + j Aceptar j
"\n";
datos += "\t- Opción seleccionada: " + campo,
Figura 9.19. Información de una opción.
selectedlndex + "\n";
} else if (campo.type -= "radio" || campo.type
"checkbox") {
datos += "\t- Valor: " + campo.valué + "\n";
datos += "\t— Seleccionado: " + campo.checked +
"\n";
} else {
datos += "\t- Texto: " + campo.text + "\n";
datos += "\t- Posición: " + campo.index + "\n";
datos += "\t- Seleccionado: " + campo.selected +
"\n" ;
}
// Mostrar las propiedades
alert(datos);
}
// Mostramos algunos campos
mostrarPropiedades(formulariol.elements["pais'M );
mostrarPropiedades(formulariol.elements["pais ] .
options[0]); ^ „ ■ m
mostrarPropiedades(formulariol.elements["país ].
options[l]); . ,
mostrarPropiedades(formulario2.elements["comprimir J),
mostrarPropiedades(formulario3.elements["pago"][0]);
mostrarPropiedades(formulario3.elements["pago” ] [2]);
</SCRIPT

Nota: Fíjese que la propiedad ñ am e para una opción devuelve


el valor u n d e f i n e d al no tenerla disponible. ______ ______

[A plica ción JavaS cript] e l

I El campo pais está en el formulario formRegistro y sus propiedades son: I


WI_ , -ID: selección1
! - Nombre: pais
-Tipo: select-one
- Deshabilitado: false
-Opciones visibles: 0
-Opciones totales: 3
-Múltiple: false
-Opción seleccionada: 1

\ Aceptar j|

Figura 9.18. Información de una lista desplegable.


Figura 9.23. Información de un campo radio.

224
M étodos ■SCRIPT TYPE="text/javascript">
var formulariol = document.forms[0];
Todos los cam pos de selección tiene estos dos métodos var formulario2 = document.forms[1];
definidos: var formulario3 = document.forms[2];
// Muestra las propiedades de un campo botón
• f o c u s ( ) , b l u r ( ) : Nos dejan establecer o retirar el foco function mostrarPropiedades(campo) {
del campo. var datos = "El campo " + campo.ñame + " está
en el formulario " + campo.form.ñame + " y
Los <INPUT> disponen además de otro adicional: sus propiedades son:\n";
datos += "\t- ID: " + campo.id + "\n";
• c l i c k ( ) : Simula un clic de ratón sobre el campo, de
datos += "\t- Nombre: " + campo.ñame + "\n";
form a que lo dejará seleccionado o deseleccionado datos += "\t- Tipo: " + campo.type + "\n";
dependiendo de su estado anterior. datos += "\t- Deshabilitado: " + campo.disabled +
"\n";
Ahora sim ularem os un clic sobre la caja de validación datos += "\t— Valor: " + campo.valué + "\n";
(checkbox) del segundo formulario y el primer boton de radio // Mostrar las propiedades
del tercero, pasados 5 y 10 segundos, respectivamente, desde alert(datos);
la carga de la página: }
// Mostramos algunos campos
<SCRIPT TYPE="text/javascript"> mostrarPropiedades(formulariol.elements["limpiar"]);
// Función que simula un clic sobre un campo mostrarPropiedades(formulariol.elements["enviar"]);
function clicCampo(campo) { mostrarPropiedades(formulario2.elements["limpiar"]);
campo.click(); mostrarPropiedades(formulario2.elements["enviar”]);
mostrarPropiedades(formulario3.elements["confirmar"] ) ;
// Inicialización de temporizador </SCRIPT>
setTimeout("clicCampo(document.forms[1].
elements['comprimir' ]) ", 5000) ; La página en h ttp ://localho st dice:
setTimeout("clicCampo(document.forms[2].
elements[ 'pago'] [0])", 10000), El campo enviar está en el formulario formReglstro y sus propiedades son:
¿h - ID: boton2
</SCRIPT> -Nombre: enviar
- Tipo: submlt
-Deshabilitado! false
- Valor:

9.2.4. Botones | Aceptar |

Como ocurre con el resto de campos de formulario, los b o­


Figura 9.24. Información de un botón.
tones son otra parte que puede ser controlada por JavaScript.
M étodos
propiedades
Por una vez, ¡todos estos elem entos tienen las m ismas En cuanto a los métodos que podrem os utilizar con los
botones, no hay ninguno nuevo, así que ya le empezarán a
propiedades! resultar incluso familiares.
• i d , d i s a b l e d , ñam e, t y p e , v a l u é : Nos perm iten
manipular los atributos que representan con el mismo • f o c u s ( ) , b l u r ( ) : Efectivamente, sirven para colocar
o quitar el foco del botón.
nombre. • c l i c k ( ) : Simula un clic de ratón sobre el botón como
• f o rm: Nos indica el formulario en el que se encuentran
si lo hubiera hecho el usuario.
los botones.
El m étodo que más nos interesa es c l i c k , y su uso es
Y como venim os haciendo con cada tipo de campo, vamos
igual que el que vimos para los campos de selección. Con el
a utilizarlas dentro de un script: siguiente código conseguiremos que se simule un clic sobre el

226 227
botón R eestablecer del primer formulario a los 10 segundos 9.3.1. Definir formulario
de haberse cargado la página. Esto hará que se borre toda la
inform ación que hubiéram os escrito en él, por lo que nueva­ Para ir poco a poco con este ejemplo, vamos a definir pri­
mente tendremos que rellenar algunos campos previamente mero un formulario que requiera registrarse como usuario, ya
para poder ver su efecto. que es uno de los más típicos con los que nos podemos encon­
<SCRIPT TYPE="text/javascript"> trar en una Web. Los datos que se piden norm alm ente son
// Función que simula un clic sobre un campo botón
• N ombre de usuario, con el cual nos identificaremos en
function clicCampo(campo) { la pagina.
campo.click() ;
Contraseña, que junto con el nombre de usuario nos
) permitirá acceder a nuestra cuenta.
// Inicialización de temporizador
setTimeout{”clicCampo(document.forms[0]. • Email, para recibir noticias o mensajes.
elements['limpiar'])", 10000);
• idiomas ^ ^ ^ página está disP onible en varios
</SCRIPT>
• Una caja de validación para autorizar al sitio Web a
9.2.5. Resumen de tipos de campos mandarnos publicidad mensual a nuestro email.

Al igual que se hizo para los valores del atributo TYPE, a estoC° dlS° H ™ L COn todos esos camP °s quedaría similar
la tabla 9.2 le permitirá tener a mano los valores que utiliza
<HTML>
JavaScript para identificar todos los posibles valores de la
<BODY>
propiedad t y p e de los campos de un formulario. Tenga en
<H3>Formulario para darse de alta como usuario en
cuenta que los elementos <INPUT> no son los únicos que dis­ nuestra Web</H3>
ponen de esta propiedad, por lo que tendremos más valores
<FORM ID=”formulario" NAME="formRegistro"
que en la tabla 9.1. ACTION-"registrar.php" METHOD="post">
Nombre de usuario: -CINPUT TYPE="text" ID-"entradal"
Tabla 9.2. Valores de la propiedad type. NAME="usuario" MAXLENGTH="8" /> (Máximo 8 caracteres)<BR />
MAMFr”T a:.,^NPÜT
NñME="clave" TYPE=”Pass»°rd» ID="entrada2 "
/><BR />
r "ampo Valores type ¡i
Repetir contraseña: <INPÜT TYPE="password" ID="entrada 3 "
Entrada de datos text, password, file, hidden, textarea ÑAME "claveRepe" /> (Deben coincidir)<BR />
Selección de datos radio, checkbox, select-one (sin atributo SIZE="4 0"^/><BR^/>= "teXt" ID="entrada4” NAME="email"
MULTIPLE), select-multiple (con atributo
tdioma: <SELECT ID="seleccionl" NAME="idioma">
MULTIPLE)
<OPTION ID="opcionl" VALÜE="EN">Inglés</OPTION>
Botones button, submit, reset
0PTION>°PTION ID="°PCÍOn2" VA1ÜE=”ES" SELECTED>Español</

</SELECT><BRN />D="OPC1°n3" VñLUE="DE" >Alemán</OPTION>


9.3. Validar datos de un formulario •.INPOT TYPE="checkbox" ID="seleccion 2 " NAME="publicidad"
</FORM>r° reC1 Publicidad mensual en mi email
Ahora que ya hem os visto cóm o se crea un form ulario </BODY>
HTML y cómo acceder a todos sus elementos y propiedades </HTML>
a través de JavaScript, vam os a aplicar todo esto en un caso
real y de los más comunes: la validación de un formulario Opcionalmente, este formulario se puede complementar
para detectar posibles errores en los datos antes de mandarlos S ¡ r d e dp" “ o los campos, es decir, un
al servidor.

228 229
Esto no es im portante ahora. Sim plem ente quería m os­
Para com probar que los campos del form ulario no con­ trarle las distintas formas que tenemos de realizar la misma
tienen errores, vam os a crear una función JavaScript por cada operación.
uno de ellos.

Formulario para darse de alta como usuario en nuestra Web


9.3.3. Validación de la contraseña
Este campo habrá dos comprobaciones:
|(Máximo 8 caracteres)
Nombre de usuario:
1. El valor de los dos campos contraseña no están vacíos.
Contraseña:
2. Los valores de ambos campos coinciden.
1 (Deben coincidir)
Repetir contraseña:
Vamos a plasmar estas validaciones en forma de código
Email:
JavaScript:
Idioma: Español ,**1

□ Quiero recibir publicidad mensual en mi email <SCRIPT TYPE="text/javascript">


// Función que comprueba la contraseña
Figura 9.25. Formulario de ejemplo. function comprobarClave(clave, claveRepetida) {
if (clave != "" && claveRepetida != "") {
return (clave == claveRepetida);
9.3.2. Validación del nombre de usuario } else {
return false;
1
Para confirm ar que este cam po es válido, sim plem ente }
vamos a mirar que su valor no esté vacío. No sería necesario </SCRIPT>
comprobar que la longitud es correcta (máximo 8 caracteres)
puesto que esa lim itación la hace el propio formulario al in­ Como puede ver, en primer lugar se comprueba que nin­
cluir el atributo MAXLENGTH en este campo. Por tanto, nuestra guno de los dos campos esté vacío, devolviendo f a l s e si esto
función devolverá un valor t r u e si el campo no es vacio y no fuese así, y a continuación se comparan sus valores devol­
viéndose como resultado.
f a l s e en caso contrario.
Tanto para el nom bre de usuario como para la contra­
< S C R IP T T Y P E = " te x t/ja v a s c r ip t" >
seña se pueden aplicar m uchas m ás validaciones, que se
// Función que comprueba el nombre de usuario
function comprobarUsuario(nombreUsuario) { dejan a elección del desarrollador de la página. Por ejemplo,
if (nombreUsuario != "” ) ( se podría restringir que el nom bre de usuario sólo pudiera
return true; contener núm eros y letras m ediante una expresión regular,
) else ( o que la contraseña deba contener m ayúsculas y m inúsculas
return false; obligatoriam ente. Las posibilidades con JavaScript son muy
amplias.

</SCRIPT>
9.3.4. Validación del email
Una forma más abreviada de definir esta función sería
utilizar el valor devuelto por la propia com paración con la Con este campo vamos a ir un poco más allá y utilizaremos
cadena vacía: cosas que ya hemos visto en esta guía. Aparte de comprobar si
<SCRIPT TYPE="text/javascriptn> el campo está vacío, validaremos también su formato a través
// Función que comprueba el nombre de usuario de una expresión regular, por lo que usaremos uno de los pa­
function c o m p r o b a r U s u a r i o (nombreUsuario) í trones que expusimos en su momento. Con esto evitaremos
return (nombreUsuario != "") ! que un usuario introduzca un texto que no corresponda a una
) d irección de correo electrónico.
</SCRIPT>
231
<SCRIPT TYPE="text/javascriptf'> 9.3.6. Validación del envío de publicidad
// Función que comprueba el email
function comprobarEmail (email) { . En este caso no hace falta comprobar si la caja está selec­
var patrón = new RegExp(-\\w+@\\w+\ \ .\\w{2,3)$ ),
cionada o no porque se trata de un campo opcional (el usuario
if (email ! = " " ) { acepta o no recibir publicidad). Por tanto, para hacer algo más
return (patrón.test(email)) ;
interesante este ejemplo y aplicar los conocimientos adquiridos,
} else {
return false; vamos a hacer que aparezca un cuadro de diálogo dándole
} una segunda oportunidad para que acepte la publicidad si el
} usuario no lo ha hecho antes.
</SCRIPT> Como siempre, esta función se puede programar de mil
formas distintas. Nosotros vamos a crearla de forma que de­
volverá un valor t r u e o f a l s e que nos servirá más adelante
9.3.5. Validación del idioma para fijar la propiedad c h e c k e d , haciendo que se acepte o no
el envío de publicidad.
Dado que en este cam po los valores siem pre van a ser
correctos ya que se seleccionan de una lista, tan solo de <SCRIPT TYPE="text/j avascript">
bem os com probar que se ha escogido una de esas opciones // Función que comprueba la publicidad
disponibles. La form a m ás sencilla de com probar esto es function comprobarPublicidad(aceptaPublicidad) {
if (¡aceptaPublicidad) {
consultar directam ente la propiedad s e l e c t e d l n c t e * de
return confirm("Nuestra publicidad le mantendrá
cam po <SELECT>. Si es distinto de -1 entonces lo darem
informado sobre las ofertas y novedades.
por válido. \n¿Desea recibirla en su email?");
) else {
<SCRIPT TYPE="text/javascript > return true;
// Función que comprueba el idioma
}
function comprobarldioma(indiceldioma) (
}
return (indiceldioma != -1 ) ! </SCRIPT>
}
</SCRIPT>
Como ha podido observar, esta función resulta bastante 9.3.7. Función principal de validación
Bueno, llega la hora de juntar todas estas funciones en una
Senofra forma de ver esto es mirar todas las opciones y buscar sola para validar nuestro formulario.
alguna que tenga su propiedad s e l e c t e d con valor t r u e . S
Como hem os definido las funciones para que devuelvan
quisiéramos hacerlo así, tendríamos que pasar directamente
un valor booleano, utilizarlas será bastante fácil. Basta con
el campo <SELECT> como parámetro y recorrer su coleccion
comprobar su resultado y m ostrar un mensaje de advertencia
de opciones: solamente cuando el cam po no sea válido. Para darle un
<SCRIPT TYPE="text/javascript"> loque más profesional a nuestra función, además del m en­
// Función que comprueba el idioma saje, situarem os el foco sobre el cam po que lo ha provocado,
function c o m p r o b a r l d i o m a (campoldioma) { con lo que ayudarem os al usuario a subsanar el error más
for (var i=0; K c a m p o l d i o m a .length; x++) i rápidamente.
if (campoldioma.options[i].selected) l
Dicho esto, vamos con la función:
return true;
■SCRIPT TYP¡S="text/javascript">
}
// Función que valida el formulario de registro
}
return false; function validarRegistro() {
with(document.formRegistro) {
)
</SCRIPT> // Comprobar campos obligatorios

233
Para hacer esto debemos utilizar el atribulo liri i jimln
if (!comprobarUsuario(usuario.valué)) {
con una función en lugar de un URL, anteponiendi ■l.i. .ulni.i
alert("El nombre de usuario está vacio.");
"javascript:" a la llamada de la función. La función til i Ii ,1
usuario.focus();
} else if (¡comprobarClave(clave.valué, exactamente igual que dentro de un bloque <S('K II"r |><■i1<>
claveRepe.valué)) { que podrá incluir parámetros o llamadas a otr.is ftun u>n< -.
alert("La contraseña está vacia o no esta Veamos un ejemplo, utilizando nuestra función p.ir.i v.ilul.ir
bien repetida."); el form ulario completo:
clave.valué =
claveRepe.valué = ""; <A HREF="javascript:validarRegistro()">Va1M.n
formulario</A>
clave .focus () ;
} else if (!comprobarEmail(email.valué)) {
alert("El email está vacio o no es válido.");
Sencillo, ¿verdad? El resultado de hacer clic sobre este en­
lace será la ejecución de la función v a lid a r R e g i :it r o.
email.select ();
email, focus () ; Tam bién podem os añadir otros enlaces que utilicen las
} else if (!comprobarIdioma(idioma. funciones de validación de cada campo a modo de prueba. Iín
selectedlndex)) { estos casos, pasaremos el valor de un campo del formulario o
alert("No hay un idioma seleccionado.'); uno escrito directamente (para que vea cómo se hace el paso
idioma.focus(); de parámetros).
}
// Comprobar campo opcional <A HREF="javascript:alert (comprobarUsuario (w ) )"I-Validar
publicidad.checked = usuario vacio</A>
comprobarPublicidad(publicidad.checked); <A HREF="javascript:alert(comprobarUsuario(document.
} formRegistro.usuario.valué))">Validar usuario del
formulario</A>
}
</SCRIPT> <A HREF="javascript:alert(comprobarClave('aa',
\"bb\"))">Validar contraseñas "aa" y "bb"</A>
Notará que el cam po p u b l i c i d a d se trata de m anera <A HREF="javascript:alert(comprobarClave(document.
distinta al resto. Esto es porque se trata de un dato opcional formRegistro.clave.valué, document.formRegistro.
y no requiere validación. Simplemente intentamos convencer claveRepe.valué))">Validar contraseña del formulario</A>
al usuario para que seleccione esa casilla por lo que, tanto si <A HREF="javascript:alert(comprobarEmail('nombre@
dominio'))">Validar email "nombre@dominio"</A>
nuestro mensaje surte efecto como si no, la propiedad c h e ck e d
<A HREF="javascript:alert(comprobarEmail('nombregdominio.
se verá modificada con un nuevo valor booleano proveniente com'))">Validar email "nombre@dominio.com"</A>
de la función c o m p r o b a r P u b l i c i d a d (ahora comprenderá <A HREF="javascript:alert(comprobarEmail(document.
mejor por qué hicim os así la función). formRegistro.email.valué))">Validar email
del formulario</A>
<A HREF="javascript:alert(comprobarPublicidad(false))">
9.3.8. Ejecutar la validación Validar publicidad false</A>
<A HREF="javascript:alert(comprobarPublicidad(document.
La manera más com ún de ejecutar una acción sobre un formRegistro.publicidad.checked))">Validar publicidad
formulario es a través de alguno de sus botones, detectando del formulario</A>
cuándo se hace clic sobre él. Lam entablem ente aún no hemos Ahora es cuando le animo, si no lo ha hecho ya, a escribir
explicado cómo detectar estas acciones, que se conocen como todo este ejem plo com pleto en su ordenador y probarlo.
eventos, aunque lo harem os en el capítulo siguiente como También puede añadir otros campos o m odificar los arriba
complemento de este. De todas formas no se preocupe que en expuestos. Todo lo que practique ahora le vendrá bien para
JavaScript hay solución para (casi) todo. Vamos a solventar esta después hacer sus scripts mucho más completos y fiables.
pequeña falta de conocim ientos actual con algo que también
le resultará útil: ejecutar funciones JavaScript desde hipervin-
culos o enlaces HTML.
235
234
10
Eventos

Un evento es una acción que realiza el usuario sobre .1l>\i ni


elemento de nuestra página al interactuar con él, como por
ejemplo pasar el puntero del ratón por encima de una imagen
o hacer clic sobre un botón.
Gracias a los eventos, la interactividad de nuestra pagina
.íumenta considerablemente ya que podremos hacer que ie
accione ante las acciones del usuario. Esta característica e%
especialmente explotada por DHTM L (Dynamic I l'l'MI.) p.u .i
crear variedad de efectos y situaciones.
JavaScript es capaz de detectar estos eventos y a la ve/ nos
permite asociarles imas instrucciones que se ejecutarán cumulo
se produzcan.

10.1. Eventos en JavaScript


En JavaScript existe una amplia variedad de eventos que
podremos utilizar a nuestro antojo para crear las situaciones
que queramos o conseguir un efecto concreto.
La tabla 10.1 le mostrará todos los eventos y la acción que
los genera.

Tabla 10.1. Lista de eventos en JavaScript.


Evento Origen

Abort La carga de una imagen es interrumpida


(detenemos la carga de la página, nos vamos
a otra...).
Load El navegador termina de cargar una página.

237
Evento Origen Tabla 10.2. Elementos HTML que generan evmiln'.
Evento Elementos
Un load Se abandona la página actual (cerramos el
navegador o nos vamos a otra). abort <img>
Error Se produce un error durante la carga de un load <body>
documento o imagen.
unload <body>
Resize Se modifica el tamaño de una ventana
error <body>, <img>
o marco.
resize <body>
Blur Un elemento de la página pierde el foco.
blur <body>, <input>, <select>, ctextan-.i
Focus Un elemento recibe el foco.
focus <body>, <input>, <select>, <textíir«'.i
Change El estado o valor de un elemento cambia.
Normalmente se origina después de que el change <input>, <select>, <textarea>
elemento haya perdido el foco (Blur). select <input>, <textarea>
Select Se selecciona un elemento de la página. keydown Elementos de entrada de datos d i• lumiul.irin.
KeyDown Una tecla es pulsada sin soltarla. keyup Elementos de entrada de datos de fui muí; irlo.
KeyUp Una tecla que estaba pulsada es soltada. keypress Elementos de entrada de datos de formulnrlo.
KeyPress Una tecla es pulsada. Se genera después de click Elementos de selección de datos y botonos de
KeyDown. formulario, <a>, <¡mg>
Click Se hace clic sobre un elemento. dblclick Elementos de selección de datos y botonas de
DbIClick Se hace doble clic sobre un elemento. formulario, <a>, <img>

MouseDown Se pulsa un botón cualquiera del ratón. mousedown Elementos de selección de datos y botones de
formulario, <a>, <img>
MouseUp Se libera un botón del ratón que estaba
pulsado. mouseup Elementos de selección de datos y botones de
formulario, <a>, <img>
MouseMove Se mueve el puntero por la pantalla.
mousemove Elementos de formulario, <a>, <img>
MouseOver El puntero entra en el área que ocupa un
elemento (se pasa por encima). mouseover Elementos de formulario, <a>, <img>
El puntero sale del área que ocupa un mouseout Elementos de formulario, <a>, <img>
MouseOut
elemento (se quita de encima). submit <form>
Submit Un formulario está a punto de ser enviado. reset <form>
Reset Un formulario es limpiado o reiniciado.

10.3. Trabajar con eventos


10.2. Eventos en una página HTML
Un evento como tal, carece de utilidad por sí mismo, así que
De momento ya conocem os los eventos que tenemos dis­ se hace necesario asociarles una función o código JavaScript
ponibles pero, ¿dónde puedo usar cada uno de ellos? Esto es que se ejecutará cuando se produzca dicho evento. A estas fun­
lo que vam os a desvelar con la tabla 10.2, donde están indi­ ciones o código se les conoce como manejadores de eventos, ya
cados los principales elem entos H TM L que desencadenan que realizan una acción específica para ese evento. Los nombres
cada evento. i)e los manejadores se definen anteponiendo la palabra "on"

238 239
al nombre del evento. De esta forma, el manejador del evento en otras publicaciones que utilizan en HREF el ctir.n Iri • 11 .i|
mohadilla(#) a m o d o de ancla al inicio de la págin.i,
C l P a i a T i l a r t e manejadores a lo , evento» disponemos de ambién podremos utilizar en el manejador l.i s rn lrn . I.i
v a r i a s opciones, gracias L la flexibilidad de JavaScr.pt. t h i s , con la que accederemos a las propiedades del ohjrlo mi.-
contiene ese manejador y así usarlas en nuestro códiúu I .1,,
es mas bien un atajo para acceder al objeto, ya que l.mil>íi<n
2. del ob¡eto que podríamos obtenerlo mediante el método getElerm -i,l m- i.i
representa el elemento. del objeto document (apartado 8.7.3 para los olvidadizo*
Ahora verem os con detalle cada una de estas opciones. como yo), pero asi nos ahorramos esa búsqueda y hmvmoN
que nuestro código resulte un poco más óptimo.
<HTML>
10 3 1. Manejadoras como atributos HTML <BODY>
<H3>Formulario que muestra propiedades</H3>
<F0RM ID="formularíol" NAME="formMensaje">
sINPOT TYPE="button" ID="botonl" NAME="botonId"
VALUE="Ver mi ID" ONCLICK="alert('Mi ID es ' + this
id);" / X B S />
^ S ^ m ^ m S T S W cuando hacemos
uaí,np-M,T,Y P E = "bUtt°n " 1D="b o t °n 2 " NAME="botonName"
VALÜE- Ver nombre formulario" ONCLICK="alert('Mi
clic sobre un botón genérico. formulario se llama ' + this.form.ñame);" / >
</FORM>
<HTML> </B0DY>
<H3>Formulario que muestra un mensaje</H3> </HTML>

| [A plicación Ja v a S c rip t]
S K -S E F ................. ... [x |

</FORM> | y Mi ID es botonl

</BODY>
</HTML> _______________ , || Aceptar f

Nota: El nombre del manejador se puede escribir- usando [A plicación Ja v a S c rip t]


indistintamente mayúsculas y minúsculas y q
f Mi formulario se llama formMensaje
HTM L no hace distinción entre a m b a s . ____________
| Aceptar j

Figura 10.1. Acceso al objeto que contiene el manejador.

<h t m l > Con estos ejemplos podemos referirnos a los objetos que
<BODY> ■H (0 1 " ONCLICK="alert('¡Mensaje tiene asociado el manejador y acceder a sus propiedades o m é ­
<A HREF="javascript.void(U)
g e n e r a d o ! ' ) ; " > V e r rtiensaje</A>
todos. Si quisiéramos acceder a otro objeto debemos escribir
el codigo de una forma normal. Veamos la manera de acceder
</BODY> a DotonName desde botonld.
</HTML>
<HTML>
En este caso hemos incluido el código en el m ^ a d o r .y
<B0DY>
<H3>Formulario que muestra propiedades</H3>
n oh ace'n ad a. »

240 241
<FORM ID="formulariol” ÑAME— MformMensaje"> <FORM ID "formulariol" NAME="formMensaje">
<INPUT TYPE=nbutton" ID="botonl" NAME=f,botonId <INPUT TYPE="button" ID="boton" NAME="mensaje"
VñLOE="Ver mi ID" ONCLICK="alert('El ID del otro boton VALUE— Pasa por encima" ONMOUSEOVER="mostrarMensajo()
</FORM>
es ' + d o c u m e n t . formMensaje.botonName.id);" /><BR />
</BODY>
CINPÜT TYPE=”button" ID="boton2" NAME="botonName"
</HTML>
VALUE="Ver nombre formulario" />
</FORM> Con este ejemplo conseguimos que se ejecute la función
</BODY>
mos tr a r M e n s a j e cuando se pulse el enlace y también cuando
</HTML>
se pase el puntero del ratón por encima del botón.
En este caso se m ostrará el ID del botonName, que es Por supuesto, también es posible utilizar funciones con pa­
"boton2". rámetros y asignarles valores usando la sentencia t h i s .
Accediendo a los objetos de esta manera, no solo podremos <HTML>
usar sus propiedades sino también sus métodos. Por ejemplo, <HEAD>
en este caso vamos a simular que hacem os clic sobre el mismo <SCRIPT TYPE="text/javascript">
botón. // Función que muestra un texto
function mostrarTexto(texto) {
<HTML> alert(texto);
<BODY> }
<H3>Formulario que muestra propiedades</H3> </SCRIPT>
<FORM ID="formulariol" NAME="formMensaje"> </HEAD>
<INPUT TYPE=”button" ID="botonl" NAME="botonId <BODY>
VALUE="Ver mi ID" ONCLICK="document.formMensaje.
<H3>Formulario que muestra propiedades</H3>
botonName.click();" /><BR />
<FORM ID="formulariol" NAME="formMensaje">
<INPUT TYPE="button" ID="boton2" NAME="botonName
<INPUT TYPE="button" ID="botonl" NAME="botonId"
VALOE="Ver nombre formulario" ONCLICK="alert( Mi
VALUE="Sumar" ONCLICK=" mostrarTexto(2+3);" / X B R />
formulario se llama ' + this.form.ñame);" />
CINPÜT TYPE="button" ID="boton2" NAME="botonName"
</FORM> VALUE="Ver nombre formulario" ONCLICK="mostrarTexto('Mi
</BODY> formulario se llama ' + this.form.ñame);" />
</HTML> </FORM>
</BODY>
Si pulsamos ahora sobre botonld entonces se ejecutará el
</HTML>
código asociado al manejador ONCLICK de botonName.
Tendiendo esto com o base, ejecutar una función al origi­ Ahora veremos algunos ejemplos con situaciones típicas en
narse un evento es tan sencillo com o definirla previam ente las que se utilizan los manejadores de eventos.
y después escribir su llam ada en el m anejador que qu e­
ramos. Acciones al cargar la página
<HTML> Este ejem plo trata de ejecu tar una función cuando se
<HEAD> com plete la carga de la página que estam os viendo. Por
<SCRIPT TYPE="text/j avascript">
// Función que muestra un mensaje tanto, el evento que nos interesa es lo a d , siendo ONLOAD su
function mostrarMensajeO { manejador.
alert("¡Mensaje generado!"); Nuestra página constará de un pequeño formulario y la fun-
} c. ion que asociaremos al manejador hará que dicho formulario
</SCRIPT> se írucialice con unos valores por defecto. Es cierto que esto lo
</HEAD> podríamos hacer directamente mediante atributos HTML, pero
<BODY> . „
<A HREF="javascript:v o i d (0)" ONCLICK="mostrarMensaje () , la finalidad de este ejemplo es que conozca el funcionamiento
de los manejadores.
Púlsame</A>

242 243
El formulario inicial sería este: F o i m u l í i i i o d e c o n v e r s ió n d e m o n e d a

<H3>Formulario de conversión de moneda</H3> 11 Dólares v il => Dólares lv l| 1


<FORM ID="formulariol" ÑAME="fo rmConver sion">
CINPUT TYPE="text" ID="entradal" NAME="cantidad" /> | Enviar consulta ]
<SELECT ID="seleccionl" NAME="monedal">
<OPTION VALUE="USD">Dólares</OPTION>
Figura 10.2. Formulario sin manejador onload.
<OPTION VALUE="EUR">Euros</OPTION>
<OPTION VALUE="GBP">Libras esterlinas</OPTION>
</SELECT> => Formulario de conversión de moneda
<SELECT ID="seleccion2" NAME="moneda2”>
<OPTION VALUE="USD">Dólares</OPTION> 11Euros v'|—
>j Libras esterlinas .v .jj l
<OPTION VALUE="EÜR”>Euros</OPTION>
<OPTION VALUE="GBP">Libras esterlinas</OPTION> ( Convertir > ]

</SELECT>
<INPUT TYPE="text" ID=”entrada2" NAME="resultado" /> Figura 10.3. Formulario con manejador onload.
<BR / X B R />
<INPUT TYPE=”submit" ID="botonl" NAME="botonConvertir" />
Cambiar imagen al pasar por encima de ella (rollover)
</FORM>
Después escribiremos la función JavaScript que se asociará Ahora veremos cómo crear un pequeño efecto que le da ni
posteriormente al manejador que nos interesa. Para evitar pro­ un toque de profesionalidad a nuestra página. El efecto rollover
blem as, lo m ejor es situarla dentro de <HEAD>. consiste en que al pasar el puntero del ratón por encima de una
imagen ésta cambie y que después vuelva a aparecer la original
<HEAD> al retirar el puntero. Esto es algo más propio de DHTM L que
<SCRIPT TYPE="text/javascript"> de JavaScript, pero así puede ir viendo todo el potencial truc
// Función que inicializa un formulario tiene por delante.
function inicializarFormulario() {
with(document.formConversion) { En este caso, nuestra página mostrará sim plemente una
monedal.selectedlndex = 1; imagen que incluye dos manejadores:
moneda2.selectedlndex = 2;
1. ONMO USE OVE R, que cambiará la imagen por otra alojada
resultado.readOnly = true;
botonConvertir.valué = "Convertir >"; en el mismo servidor al poner el puntero encima de ella.
} 2. ONMOUSEOUT, que volverá a mostrar la imagen que es­
> taba al cargar la página, una vez quitemos el puntero.
</SCRIPT>
</HEAD>
Para realizar este ejem plo vam os a trabajar con las si­
guientes imágenes:
Por último, gracias al manejador ONLOAD colocado en la
etiqueta <BODY> conseguirem os que:
1. Nuestras listas desplegables tengan unos valores con­
cretos seleccionados. d e r e c h a .g if lz q u ie rd a .g if
2. La segunda caja de texto sea únicamente de lectura. Figura 10.4. Imágenes de ejemplo.
3. El botón de envío tenga el texto que nosotros que­
ramos.
Al principio mostraremos una de ellas, quedando así el
<BODY O N L O A D="inicializarFormulario ();"> código HTML:
En las siguientes figuras puede ver la diferencia que existiría •:H3>Mueve el puntero sobre la imagen</H3>
entre los formularios aplicando o no esta función. <IMG ID="imagen1" NAME="flecha" SRC="derecha.gif" />

244 245
A continuación declaramos, en el <HEAD>, las funciones imagen.src = "derecha.gif";
que cambiarán la imagen cuando se provoque el evento co­ }
rrespondiente. Para ello, debemos utilizar la propiedad s r c I I Función que cambia la imagen original
function cambiarOriginal(imagen) {
del objeto de la imagen.
imagen.src = "izquierda.gif";
<HEAD> }
<SCRIPT TYPE="text/javascript"> </SCRIPT>
// Función que muestra la imagen original </HEAD>
function m o s t r a r O r i g i n a l () í
document.flecha.src = "derecha.gif"; Por supuesto, tam bién debem os cam biar Invéntenle ln?.
manejadores:
// Función que cambia la imagen original
<IMG ID="imagenl" NAME="flecha" SRC="derechd ,i| II"
function c a m b i arOriginal() {
document.flecha.src = "izquierda.gif"; ONMOUSEOVER="cambiarOriginal (this) ; " 0NM0USE01IT "ni.. Ii.n
Original(this);" />
}
</SCRIPT> Y ahora ya podemos añadir este rollover todas l.is vives
</HEAD> que queramos en la m isma página:
Para terminar, asociaremos estas funciones a los maneja-
<IMG ID="imagen2" NAME="otraFlecha" SRC="derei:h.i.iji ( "
dores de la imagen: ONMOUSEOVER="cambiarOriginal (this) ;" 0NM0U5K0UT "nn>:.l i. 11
<IMG ID="imagenl" NAME=" flecha" SRC="derecha. Original(this);" />
gif" 0NM00SE0VER="cambiarOriginal(>;" <IMG ID="imagen3" NAME="flechita" SRC="derecha.q I ("
ONMOOSEOUT="mostrarOriginal();" /> ONMOUSEOVER="cambiarOriginal (this) ; " ONMOUSEOUT- "mOMt 1 .it
Original(this);" />
Si cargamos esta página y pasamos el puntero por encima de
la imagen verem os cómo se produce el efecto deseado. Como Operaciones sobre formularios
puede ver, no es en absoluto complicado y sin embargo eleva
la categoría de nuestra página. El incluir manejadores en elementos de un formulario es
Por aplicar un poco lo que hem os ido aprendiendo, me uno de las usos más comunes de JavaScript ya que nos ofrece
voy a poner un poco quisquilloso y voy a preguntarle que un control sobre ellos que es impensable a través de código
pasaría si en nuestra página necesitásem os hacer este ro- HTML.
llover en varias partes. Tal y com o tenem os escritas las fun­ Para empezar por algo sencillo, vam os a imaginar que te­
ciones, necesitaríam os crearlas para cada im agen ya que su nemos un formulario con varios tipos de campos y queremos
código apunta a una en concreto (en el ejem plo, la que tiene validarlos antes de enviar la información al servidor.
el nom bre f l e c h a ) . ¿No cree que existe una m anera mas <H3>Formulario de acceso</H3>
óptim a de escribir estas funciones para que nos valgan en <FORM ID="formulariol" NAME="formLogin" ACTION="login.php"
cualquiera de las im ágenes? ¡Acertó! (Y si no, no se preocupe METHOD="post">
que no m e voy a en tera r...) Tenem os algo trem endam ente Usuario <INPUT TYPE="text" ID="entradal" NAME="usuario"
MAXLENGTH= "8 " / X B R />
útil para solucionar esto: la sentencia t h i s . Com o esta sen­
Contraseña CINPUT TYPE="password" ID="entrada2"
tencia hace referencia al objeto que contiene el m anejador, MAME="clave" / X B R />
no tenem os m ás que trasladarla com o parám etro a las fun­ •-INPUT TYPE="button" ID="botonl" NAME="botonValidar"
ciones que cam bian la im agen para poder u sarlas tantas VALUE="Validar" /> <INPUT TYPE="submit" ID="boton2"
veces com o queram os. NAME="botonEnviar"/>
•/FORM>
<HEAD>
<SCRIPT TYPE="text/ javascript" > Después tendremos nuestra función que validará el for­
// Función que muestra la imagen original mulario comprobando que sus dos campos tienen un valor
function mostrarOriginal(imagen) {
asociado, es decir, no están vacíos:

247
)
<HEAD> </SCRIPT>
<SCRIPT TYPE="text/javascript"> </HEAD>
// Función que valida el formulario <BODY>
function validarFormulario 0 { <H3>Formulario de acceso</H3>
// Operaciones de validación <FORM ID="formulariol" NAME="formLogin" ACTION="login.php"
w i t h (document.formLogin) {
METHOD="post">
if (usuario.valué == "") í Usuario CINPUT TYPE="text" ID="entradal" NAME="usuario"
u s u a r i o .fo c u s (); MAXLENGTH="8" / X B R />
} else if (clave.valué == "") t Contraseña <INPÜT TYPE="password" ID="entrada2"
clave, focus () ; NAME="clave" / X B R />
CINPÜT TYPE="button" ID="botonl" NAME="botonEnviar"
} 0alert("¡Todo correcto! Puedes enviar el
VALUE="Validar y enviar"
formulario."); ONCLICK="validarYEnviarFormulario();" />
} </FORM>
} </BODY>
} </HTML>
</SCRIPT>
</HEAD> Con esta función conseguimos que sólo se envíe el formulario
Hasta ahora habíamos visto cómo salir del paso utilizando si los dos campos tienen algún texto escrito. En otro caso, se fija el
un Íüpervínculo y su atributo HREF para lanzar la validación, foco en el campo que esté vacío para que el usuario lo rellene.
pero para hacerlo a través de un botón debemos usar el m a Otro lugar típico del formulario donde incluir un manejad o r
nejador ONCLICK. De este modo, nuestro codigo quedaría tan de eventos, en concreto ONCHANGE, es en las listas de selección.
Con esto podremos ejecutar unas acciones cuando se seleccione
simple como:
una de sus opciones. En estos casos se hace bastante uso de la
<INPOT TYPE="button" ID="botonl" NAME="botonValidar"
VALUE="Validar" ONCLICK="validarFormular10(), sentencia t h i s , sobre todo para obtener el índice o el valor de
la opción seleccionada.
De esta forma obligamos al usuario a pulsar dos botones Suponiendo este pequeño formulario:
nara enviar la información: uno para validar y otro para enviar.
Entonces como extensión de este ejemplo, podríamos unificar <H3>Adivina la mezcla de colores</H3>
<FORM ID="formulariol" NAME="formColores">
S S o n e s de los dos botones, en ^ , ^ ^ 0^ Rojo +
envíe el formulario únicamente si la val dacion ha sido ss <SELECT ID="seleccionl" NAME="color">
factoría Para ello debemos hacer uso del método s u b m it de <OPTION VALUE="Verde">Verde</OPTION>
formulario dentro de la función que comprueba los campos. COPTION VALUE="Azul">Azul</OPTION>
<OPTION VALUE="Amarilio">Amaril1o</OPTI0N>
<HTML> </SELECT>
<HEAD> « Naranja
¿ S C R IP T TYPE="text/javascript >
</FORM>
// Función que valida y envia el formulario
function v a l i d a r Y E n v i a r F o r m u l a n o {
Y creando esta función que comprueba si hem os seleccio
// Operaciones de validación
with(document.formLogin) {
nado la opción correcta, mostrando un m ensaje al usuario:
if (usuario.valué == "") ( <HEAD>
u s u a r i o .f o c u s (); •'.SCRIPT TYPE="text/javascript">
} else if (clave.valué == "") í // Función que comprueba la opción seleccionada
clave.focus () ; function comprobarMezcla(indiceColor) {
} else ( if (indiceColor == 2) {
submit () ; alert("¡Muy bien!");
) ) else {
)
249
248
alert("Lo siento, no es este color-
inténtalo de nuevo."); Más profesional así, ¿verdad? Gracias a la sentencia i l . !
hemos podido acceder al array de opciones d e ln lisia v , ,il
}
) mismo tiempo, hemos obtenido el índice seleccionado paia
</SCRIPT> usarlo como índice de ese array y así conseguir la opción i o
C/HEAD> rrespondiente. Es un poco más complejo de escribir, pero en
Podremos finalmente asociarla al manejador ONCHANGE algunas situaciones es una de las mejores elecciones.
para dotar de "inteligencia" a nuestro formulario:
<SELECT ID="seleccionl” NAME="color" 10.3.2. Trabajar con eventos en JavaScript
ONCHANGE="comprobarMezcla(this.selectedlndex) >

Si el usuario elije la opción correcta (Amarillo, opción con Adem ás de incluir m anejadores de la manera que aca­
índice 2) se le mostrará un mensaje de enhorabuena. En otro bamos de ver, tam bién es posible hacerlo directam ente en
caso, se le anima a intentarlo otra vez. nuestros scripts sin añadir atributos adicionales a los elementos
Para ir un paso más allá con este ejemplo, podríamos pasar HTML.
a la función comprobarMezcla directamente el objeto que Los manejadores de cada objeto se utilizan como una pro­
representa la opción, para así poder obtener tanto su índice piedad más de éste, por lo que a estas alturas no le será muy
como su valor y así mostrar un mensaje más completo. El script difícil de comprender. En este caso, al manejador se le debe
nos quedaría algo similar a esto: asignar siem pre una función ya que si ponemos directamente
una porción de código el resultado no será el esperado puesto
<HTML> que se ejecutará como parte del script. Veamos un ejemplo con
<HEAD>
<SCRIPT TYPE="text/javascript">
el evento c l i c k .
// Función que comprueba la opción seleccionada ■SCRIPT TYPE="text/javascript">
function comprobarMezcla(color) { // Función que muestra un mensaje
if (color.index = = 2 ) { function mostrarMensaje() {
alert("¡Muy bien!"); alert("¡Hola!");
} else ( }
alert("Lo siento, no es " + color.valué
// Asignación incorrecta de manejador
Inténtalo de nuevo."); objeto.onclick = alert("¡Hola!");
} // Asignaciones correctas de manejador
} objeto.onclick = mostrarMensaje;
</SCRIPT> objeto.onclick = function mostrarMensaje() {
</HEAD> alert ("¡Hola!"); }
<BODY> •:/SCRIPT>
<H3>Adivina la mezcla de colores</H3>
<FORM ID="formulariol" NAME="formColores"> En el código que acabamos de escribir verá que si asignamos
Rojo + directamente una llamada al método a l e r t , el manejador no
<SELECT ID="seleccionl" NAME="color”
contendrá dicha instrucción sino su resultado (u n d e fin e d
ONCHANGE="comprobarMezcla(this.options[this.
para el caso de a l e r t ) . Sin embargo, si asignamos una fun­
selectedlndex])">
COPTION VALÜE="Verde">Verde</OPTION> ción o la definimos directamente sobre la marcha, será algo
<0PTI0N VALUE="Azul”>Azulc/OPTION> completamente válido y el manejador hará su papel tal y como
COPTION V A L ü E = " A m a r i l l o " > A m a r i l l o C / O P T I O N > esperamos.
c/SELECT>
= Naranja
Nota: Los nombres de los manejadores deben estar escritos
c/FORM>
C/B0DY>
siempre en minúsculas para trabajar con ellos desde código
C/HTML> JavaScript.

250 251
Algo que debe tener en cuenta al utilizar los manejadores
de este modo es que las asignaciones deben hacerse al final de s s H ° ™ r n ,° ' tal y como ° curría ai .............................. ..
la página o después de que se haya cargado, para que los ele­
<HTML>
mentos HTM L a los que hagamos referencia estén definidos.
<HEAD>
<HTML> CSCRIPT TYPE="text/javascript">
CHEAD> // Función que muestra un ID
<SCRIPT TYPE=" text /j avascript "> function mostrarID() {
// Función que muestra un mensaje alert("Mi ID es " + this.id);
function mostrarMensaje () {
alert("¡Clic!"); C/SCRIPT>
} C/HEAD>
document.formBotones.botonAntes.onclick = CBODY>
mostrarMensaje; ■-H3>Pulsa en los botonesC/H3>
</SCRIPT> CFORM ID="formulariol" NAME="formBotones">
</HEAD>
<BODY> VALUET "MYPE~"bUtt°n
VALUE="Mira " ID="botonl" NAME="botonIdl"
mi ID" />
<H3>Pulsa en los botones</H3>
<FORM ID="formulariol" NAME="formBotones"> VALUET"MYPE="bUtt°n"
VALUE="Mira mi ID" /> ID="boton2" NAME="botonId2"
<INPUT TYPE="button" ID="botonl" NAME="botonAntes" </FORM>
VALDE="Manejador erróneo" /> <SCRIPT TYPE="text/javascript">
CINPUT TYPE="button" ID="boton2" NAME="botonDespues"
document.formBotones.botomd!.onclick = mostrarID;
VALUE=”Manejador válido" />
C/F0RM> </sSl P T > n °rmB0t0neS-b0t0nId2-°nClÍCk " mostrarID;
CSCRIPT TYPE="text/javascript"> ■Vb o d y >
document.formBotones.botonDespues.onclick = </HTML>
mostrarMensaj e;
C/SCRIPT>
C/BODY> haSte ahor!r Pl° mU6Stra 1111poco todo Io clue se ha ido diciendo
C/HTML>

Si escribe este código y trata de pulsar en cada uno de los p ág m T ,Ón SS aS° CÍa al maneÍador en la Parte final de la
botones, comprobará que el prim ero no realiza ninguna ac­ La función hace referencia al objeto que provoca el
ción, mientras que el segundo sí muestra el m ensaje previsto. evento y no siempre alude al mismo.
Esto es porque la asignación de la función m o stra rM e n sa j e
al manejador o n c l i c k de b o to n A n te s se hace al principio Para que vea m ejor el contraste de incluir manejadores de
de la página donde, ni el botón ni el formulario estaban aún ° ™ a, vamos a utilizar los mismos ejemplos que con los
definidos en ella. manejadores por HTML. 4 ün ,os

Acciones al cargar la página


Nota: Un inconveniente que presenta esta manera de usar
los manejadores, es que no podremos pasar parámetros a las Para refrescarle la memoria, aquí tratamos de ejecutar una
funciones. La alternativa que nos queda es utilizar variables
de ámbito global para poder recoger su valor dentro de las *'^ m ím ejadoronloY ¿r Caí^a actual, utilizando
funciones asignadas a los eventos.
con y ‘a fm’Ctón ‘°
Para utilizar la sentencia t h i s , tendremos que hacer re­ IITML>
ferencia a ella dentro de las funciones que asociemos al ma­ HEAD>
nejador de m odo que t h i s representará al objeto que ha •/SCRIPT TYPE="text/javascript">

252
253
// Función que inicializa un formulario 1. onmouseover, para cambiar la imagen por otra al poner
function inicializarFormulario() { el puntero encima de ella.
with(document.formConversion) { 2. onmouseout, para volver a m ostrar la im agen que
monedal.selectedlndex = 1; estaba, una vez quitemos el puntero.
m o n e d a 2 .s e l e c t e d l n d e x = 2;
resultado.readOnly = true; <HTML>
botonConvertir.valué = "Convertir >"; <HEAD>
<SCRIPT TYPE="text/javascript">
}
// Función que muestra la imagen original
} function mostrarOriginal() {
</SCRIPT>
this.src = "derecha.gif";
</HEAD>
<BODY>
}
<H3>Formulario de conversión de moneda</H3> // Función que cambia la imagen original
<FORM lD="formulariol" NAME="formConversion > function cambiarOriginal() {
<INPUT TYPE— "text" ID="entradal" NAME="cantidad /> this.src = "izquierda.gif";
<SELECT ID="seleccionl" NAME="monedal"> }
<OPTION VALUE="üSD">Dólares</OPTION> </SCRIPT>
COPTION VALUE="EUR">Euros</OPTION> </HEAD>
<OPTION VALOE="GBP">Libras esterlinas</OPTION> <BODY>
<H3>Mueve el puntero sobre la imagen</H3>
</SELECT> =>
<SELECT ID="seleccion2" NAME="moneda2"> <IMG ID="imagenl" NAME="flecha" SRC="derecha.gif" />
COPTION VALUE="OSD">Dólares</OPTION> <SCRIPT TYPE="text/javascript">
<OPTION VALUE="EUR">EuroS</OPTION> // Asignamos los manejadores
<OPTION VALÜE="GBP">Libras esterlinas</OPTION> document.flecha.onmouseover = cambiarOriginal;
</SELECT> document.flecha.onmouseout = mostrarOriginal;
CINPÜT TYPE="text" XD= "entrada2,? NAME="resultado /> </SCRIPT>
</BODY>
<BR /><BR /> .
<INPUT TYPE="subrait" ID="botonl" NAME="botonConvertir </HTML>
</FORM> Como ve, nos quedan unas funciones bastante simples si
<SCRIPT TYPE="text/javascript">
// Asignamos el manejador
utilizamos la sentencia thi s ya que, al provocarse los eventos,
window.onload = inicializarFormulario; las funciones la enlazan con el objeto de imagen. Tam bién po­
</SCRIPT> dríamos haber escrito la ruta completa (document.flecha.
</BODY> src) pero no estaríamos aprovechando el potencial de asignar
</HTML> los manejadores m ediante código JavaScript.
Para que la función se ejecute después de la carga de la pá­
gina, debem os usar el m anejador onload del objeto window O peraciones sob re form u lario s
y no de document como se podría pensar. En realidad po­
El primer manejador que vamos a ver, en los ejemplos re­
dríam os haber asignado este m anejador en el <HEAD> puesto
lacionados con los formularios, será onclick a través de un
que el objeto window ya existe en ese m om ento, pero es un
botón. Este manejador ejecutará una función que validará los
caso excepcional y le recom iendo hacer estas asignaciones
campos existentes en el formulario.
siem pre al final para m antener una hom ogeneidad en su
código. •IITML>
■MEAD>
•SCRIPT TYPE="text/javascript">
C am biar im agen al pasar por encim a de ella (rollover)
// Función que valida el formulario
function validarFormulario() (
Aquí se pretende crear un efecto de rollover mediante el uso
// Operaciones de validación
de dos manejadores de un objeto de imagen:
255
254
<HTML>
with(document.formLogin) {
<HEAD>
if (usuario.valué == "") (
<SCRIPT TYPE="text/javascript">
usuario.focus() ;
) else if (clave.valué == "") 1 // Función que comprueba la opción seleccionada
clave, focus () ; function comprobarMezcla() {
if (this.selectedlndex == 2) {
} else {
alert("i Todo correcto! Puedes enviar el alert(" ¡Muy b i e n !");
) else {
formulario.11) l
aJ-ert ("Lo siento, no es este color... Inténtalo
) de nuevo.");
} 1
} }
</SCRIPT> </SCRIPT>
</HEAD> </H EA D >
<BODY> <BODY>
<H3>Formulario de acceso</H3>
<FORM ID="formulariol" NAME="formLogin" ACTION-"login.php <H3>Adivina la mezcla de colores</H3>
<FORM ID="formulariol" NAME="formColores">
METHOD="post"> .. . „ Roj o +
Usuario <INPUT TYPE="text" ID="entradal" ÑAME- usuario
<SELECT ID="seleccionl" NAME="color">
MAXLENGTH="8" / X B R />
Contraseña <INPUT TYPE="password" ID="entrada2 <OPTION VALUE="Verde">Verde</OPTION>
<OPTION VALUE="Azul">Azul</OPTION>
NAME="clave" / X B R /> .
•CINPUT TYPE="button" ID="botonl" NAME="botonValidar <OPTION VALUE="Amarillo">Amarillo</OPTION>
</SELEC T>
VALUE="Validar" /> .„ Naranja
<INPUT TYPE=”submit” ID="boton2" NAME-"botonEnviar />
< / FO RM >
<SCRIPT TYPE="text/javascript',>
•:SCRIPT TYPE="text/j avascript">
// Asignamos el manejador
document.formLogin.botonValidar.onclick I I Asignamos el manejador
validarFormulario; document.formColores.color.onchange = comprobarMezcla;
■:/SCRIPT>
</SCRIPT> • :/ BO D Y >
</BODY> •:/HTML>
</HTML>
N ada complicado, como puede comprobar. Únicamente Ocurre lo mismo cuando queremos acceder al objeto que
cambia la forma de asignar el manejador respecto al método representa la opción seleccionada para obtener su índice y
por HTML. En la versión extendida del ejemplo, donde uni­ valor, siempre dentro de la función.
ficamos las acciones de los dos botones en uno sólo (envío y • MTML>
validación), sería exactamente igual pero utilizando el mane­ ■IIEAD>
jador del botón correspondiente. ÜCRIPT TYPE="text/javascript">
// Función que comprueba la opción seleccionada
<SCRIPT TYPE="text/javascript"> function comprobarMezcla() {
// Asignamos el manejador // Obtenemos la opción seleccionada
document.formLogin.botonEnviar.onclick - var opcionSeleccionada = this.options[this.
validarYEnviarFormulario; selectedlndex];
</SCRIPT> if (opcionSeleccionada.index = = 2 ) (
alert(" ¡Muy b i e n !");
Ahora es el turno del manejador o n c h a n g e de las listas
} else {
desplegables. El uso de la sentencia t h i s es casi el pan nuestro
alert("Lo siento, no es " + opcionSeleccionada.
de cada día, pero recuerde que aquí siem pre se debe usar valué + "... Inténtalo de nuevo.");
dentro de las funciones y no como un parám etro de la misma, }
de modo que nos quedaría así: }

256 257
</SCRIPT> <SCRIPT TYPE="text/javascript">
</HEAD> // Función que muestra un mensaje
<BODY> function mostrarEvento(evento) {
<H3>Adivina la mezcla de colores</H3> alert (evento) ;
<FORM ID="formulariol" NAME="formColores"> }
Rojo + // Asignaciones al manejador (forma 1)
<SELECT ID="seleccionl" NAME="color"> document.onclick = mostrarEvento;
<OPTION VALUE="Verde">Verde</OPTION> // Asignaciones al manejador (forma 2)
<OPTION VALÜE="Azul">Azul</OPTION> document.onclick = function mostrarEvento(evento) {
< O P T I O N V A L U E = ”A m a r i l l o " > A m a r i l l o < / O P T I O N > alert(evento); }
</SELECT> </SCRIPT>
= Naranja
</FORM> Si observamos el código, vemos que hemos puesto un pará­
<SCRIPT TYPE="text/javascript"> metro a la función usada en el manejador. ¿Cómo es posible si
// Asignamos el manejador habíamos dicho que esto no se podía hacer? Esto es así porque
d o c u m e n t .formColores.color.onchange = comprobarMezcla;
en realidad no estam os pasando un parámetro sino dando un
</SCRIPT> nombre al objeto e v e n t que JavaScript está creando automá-
</BODY>
I icamente. También se puede omitir ese nombre y recuperar el
</HTML>
objeto con a rg u m e n ts [ 0 ] dentro de la función.
Com o ya no podem os usar parám etros, lo que hem os La asignación se puede hacer de las dos maneras mostradas,
hecho ha sido obtener la opción seleccionada directam ente ya que consiguen el mismo resultado.
dentro de la función gracias a que tenem os acceso completo
al objeto que representa la lista desplegable, m ediante la A dvertencia: Estas son la form as estándar de recuperar el
sentencia t h i s . objeto e v e n t. En Internet Explorer también se puede acceder
a él desde w indow . e v e n t.

10.4. El objeto event Si utilizásemos el código anterior, conseguiríamos un men­


saje como el de la figura 10.5 al hacer clic sobre cualquier parte
de la ventana de nuestro navegador. No nos dice mucho de
Aún después de todo lo explicado, JavaScript nos tiene momento, pero ahora veremos cómo sonsacarle la información
preparado un as más bajo la manga. i|ue tiene guardada.
Cuando se produce un evento, se crea automáticamente
un objeto (e v e n t) que contiene un conjunto de información
[Aplicación Ja v a S c rip t]
(SI
acerca de ese evento. Este objeto podrá ser utilizado mientras
se produce ese evento, de modo que desaparecerá cuando fi­ y [object MouseEvent]

nalice, también de manera automática.


j¡ Aceptar |
Siendo estrictos, este objeto tiene un m ayor protagonism o
en códigos relacionados con D H TM L pero quiero presen­
társelo ya que creo que es im portante conocerlo, aunque Figura 10.5. Recuperación del objeto event.
sea un poco, para tener una buena base de los eventos de
JavaScript. 10.4.1. Propiedades
Ahora se estará preguntando cómo y dónde podemos usar
este nuevo objeto. Bien, vam os a ello. El objeto e v e n t es ac­ En la tabla 10.3 se mostrará un listado de las principales
cesible dentro de las funciones asignadas en los manejadores. propiedades estándar que contiene el objeto e v e n t . Existen
¿Cómo lo recuperamos? Veam os m ejor un sencillo ejemplo •tlgunas más pero, al ser propias de algunos navegadores o muy
con el evento c l i c k . específicas de DHTML, no las vamos a tratar en este libro.

258 259
Tabla 10.3. Propiedades del objeto event [Aplicación Ja va S c rip t]

Tipo Descripción y altKey: false


! _ ’» button: 0
dlentX: 278
Booleano Devuelve true cuando se ha presionado dientY: 21
altKey ctrlKey: false
la tecla Alt. type: click
screenX: 567

button Entero Indica el botón del ratón que ha sido screenY: 260
shtftKey: false
pulsado. Ver tabla 10.4.
Entero Indica la posición horizontal del cursor
clientX
donde se ha hecho clic, dentro del área
del documento, según el código que vimos en el apartado an­
disponible en el documento. terior.
clienteY Entero Indica la posición vertical del cursor Figura 10.6. Propiedades de un evento.
donde se ha hecho clic, dentro del
área disponible en el documento.
Para terminar con este objeto, tenga siem pre presente que
Booleano Devuelve true cuando se ha presionado en una página pueden lanzarse varios eventos al realizar una
ctrlKey
la tecla Ctrl. acción. Un caso muy claro es el que hemos estado viendo con
String Indica el tipo de evento que se ha c l i c k . Cuando pulsamos sobre una parte del documento,
type
producido (click, mouseover, etc.). no sólo estamos provocando dicho evento sino que, en esté
Indica la posición horizontal del cursor caso, ademas se producen otros dos: mousedown y mouseup.
screenX Entero
donde se ha hecho clic, dentro de la Aunque no tengam os un m anejador asociado a ellos, los
resolución de pantalla del usuario. eventos siempre van a producirse. Ahora la duda que nos
queda es ¿en qué orden aparecen? Para esta acción los eventos
screenY Entero Indica la posición vertical del cursor
siguen esta secuencia:
donde se ha hecho clic, dentro de la
resolución de pantalla del usuario. 1. mousedown: al hacer la pulsación sobre el botón del
Devuelve true cuando se ha presionado ratón.
shiftKey Booleano
la tecla Shift. 2. mouseup: al soltar el botón.
3. c l i c k : al soltar ei botón tam bién, pero después de
mouseup.
Tabla 10.4. Valores de la propiedad button
Si nos construimos un sencillo código podremos ver esta
Navegador Descripción secuencia.
I Valor
Botón izquierdo del ratón •FORM NAME="formEventos">
0 Estándar <TEXTAREA NAME="eventos" ROWS="9"></TEXTAREA>
Estándar Botón central del ratón •/FORM>
1
Botón derecho del ratón •SCRIPT TYPE="text/javascript">
2 Estándar
// Función que añade un evento en el textarea
Internet Explorer Botón izquierdo del ratón function pintarEvento(evento) {
1
Internet Explorer Botón derecho del ratón document.formEventos.eventos.valué += evento.type
2 + "\n";
Internet Explorer Botón central del ratón }
4
// Asignamos los manejadores (no importa el orden)
document.onclick = pintarEvento;
La figura 10.6 muestra un ejemplo de la información con­ document.onmousedown = pintarEvento;
tenida en el objeto event cuando se hace clic en alguna parte document.onmouseup = pintarEvento;
</SCRIPT>

260 261
yy
Cookies

Una cookie no es más que una porción de inform ación que


se alm acena tem poralm ente en el ordenador del usuario con
la finalidad de poder recuperarla en cada visita una misma
página y así evitar tener que introducirla una y otra vez.
listo hace que la navegación del usuario sea m ás cóm oda y
pueda ir directam ente a la sección que le interese de nuestra
página.
La inform ación que se suele guardar en las cookies es in-
Iroducida por el usuario cuando entra por primera vez a la
página, para poder mostrarle unos datos más personalizados
o simplemente para ahorrarle tiempo en su próxim a visita.
Algunos ejemplos de la utilidad de las cookies son:
• Nombre de usuario. Crea la sensación de que la página
"recuerda" nuestro nombre de usuario cuando volvemos
a visitarla.
• Fecha última visita. Esto puede tener utilidad sobre todo
en los foros para saber el tiem po que llevas sin entrar,
por ejemplo.
• Colores de la página. Si la página nos perm ite perso­
nalizar el aspecto que puede tener, es de gran ayuda
almacenar esas preferencias para que el usuario no tenga
que volver a configurarlo una y otra vez.
• Tienda más cercana. A las páginas que muestren ofertas
de productos les puede ser útil alm acenar este dato
para ofrecer al usuario una inform ación más persona­
lizada.
I lace tiempo, las cookies se usaban para almacenar los pro-
•Indos que se iban seleccionando en una W eb de ventas, al
f*»lilo de un carrito de la compra, pero con el aumento del uso

263
de lenguajes de lado servidor, como PHP o ASP, esto ha caído C onfigu ra ción a v a n zad a de privacidad
en desuso y ahora se utiliza la sesión que mantiene el usuario
I E!i|a la forma de administrar las cookiej en U rtwu» •!» (m o t* I
con el servidor como medio para guardar esa cesta. I Esto invalida la administración automática .1^ (

1 Cookies

Advertencia: A la hora de crear nuestras propias cookies ! 0ÍnY3![daí la administración aütomatíca de cookie^

debemos evitar guardar en ellas información confidencial


Cookies de origen Cookies de tercero»
del usuario, como pueden ser contraseñas, nwnet o de DNI,
© ¿ceptar © Aceptar
número de tarjetas de crédito, etc. Hacerlo supondría un alto O Bloquear O BJoquear
riesgo puesto que esos datos podrían ser recuperados por una O Preguntar O Preguntar

página creada para tal propósito. _________ ________ __ i’ D Aceptar siempre las cookies de sesión j

Como hemos dicho, las cookies se almacenan en el ordenador 1 t Aceptar J [ 1 »|« | 1

de usuario, pero ¿dónde exactamente? Al igual que muchas


Figura 11.1. Administración de cookies en Interna! I xplorm
otras cosas, cada navegador tiene definido un sitio y una m a­
nera de guardarlas:
• Internet Explorer: Para sistemas Windows, la ruta típica
e s " C : \Documents and Settings\<su_usuario>\
Cook i e s ", donde cada cookie se almacena en un fichero
Historial
distinto. Firefox eodrá: j Usar una configuración personalizada para el historial v |
• FireFox: Tam bién para W indows, en la carpeta C : \
Documents and Settings\<su_usuario>\Datos □ Abrir automáticamente Firefox en una sesión de navegación privada

de p r o g r a m a \ M o z i l l a \ F i r e f o x \ P r o f i l e s \ < s u _ 0 Recordar el historial de búsqueda al menos I 9 * I días

0 Recordar el historial de descargas


p e r f i 1>". Ahí podrem os encontrar los archivos " c o ­
ok i e s . txt" y " h o s t p e r m . l " que almacenan todas
0 Aceptar cookies I Excepciones... ]
las cookies juntas. 0 Incluso las de terceros

JavaScript guarda todas las cookies dentro de la propiedad Mantener hasta que: [caduquen vj |Mostrar cookies... ]

c o o k i e del objeto d ocument. U Limpiar el historial cuando Firefox se cierre . Corifhtfjtqtion


Hay que señalar que las cookies no permanecen en nuestro
ordenador hasta la eternidad sino que tienen una fectm de cuando se use la barra de direcciones, sugerir: [Historial y marcadores
w-l
expiración o caducidad, que puede ser de unos segundos,
horas, días o simplem ente hasta cuando cerremos la ventana \ Aceptar j | Cancelar | | Ayyda ]
del navegador. .
Opcionalmente, es posible activar o desactivar el almace­
Figura 11.2. Administración de cookies en FireFox.
namiento de cookies desde las opciones del navegador, aunque
por defecto suele venir activada.
• En Internet Explorer debemos pasar por H erram ientas> 11.1. Trabajar con cookies
O pciones de lnternet>P rivacidad>A vanzada. Una vez
ahí tenemos la posibilidad de cambiar la administración
11.1.1. Estructura de una cookie
de las cookies. Ver figura 11.1.
• En FireFox es más sencillo. Si vam os a H erram ientas> La manera de almacenar las cookies en JavaScript es en forma
Opciones>Privac¡dad veremos una sección dedicada a 1I1' pares campo=valor, separando cada par por un punto v
las cookies. Ver figura 11.2. coma ( ;) . '

264 265
puede ser HTTPS (HTTP Secure). Este el único campo
La información m ínim a y obligatoria que debe contener
que no lleva un valor asociado ya que está representado
cada cookie es un campo para el dato que queremos guardar
por si mismo. Si no se especifica, entonces la cookie se
(nombre de usuario, fecha de última v isita...) y su valor co­
manda independientemente del protocolo que se esté
rrespondiente. Este valor no puede contener los caracteres
utilizando.
punto ( . ) , punto y coma ( ; ) y el espacio en blanco, pe
caso de que estuvieran habría que reemplazarlos por valores Dicho todo esto, una cookie que almacenase el nombre de
UNICODE mediante la función e s c a p e . usuario tendría este aspecto sin campos opcionales:
A partir de aquí, se pueden añadir otros campos opcionales usuario=Pepe
como son:
Y este otro con algún campo opcional:
. expires: Indica la fecha de caducidad de la cookie
sólo cuando no queremos que desaparezca al cerrar e usuario=Pepe;expires=Tue, 3 Mar 2009 18:24:41 GMT;secure
navegador. Esta fecha debe estar expresada en formato Dado que todos los cam pos, obligatorios u opcionales,
GMT, por lo que aquí nos será de mucha ayuda el mé­ van separados por punto y coma ( ;) , se hace difícil delimitar
todo toGMTString del objeto Date. _ dónde acaba cada cookie. Una regla que se suele utilizar es la
• doma i n: Indica a qué servidor debe ser enviada la cookie. de insertar un espacio en blanco después del punto y coma
Si no se incluye este campo, entonces se toma el dominio de los campos opcionales. De esta forma podremos saber que
que ha creado la cookie. Al especificar un dominio, la co­ una cookie comienza por aquel campo que no tenga ese espacio
okie puede ser enviada también a todos sus subdommios en blanco.
si no se pone explícitamente: usuario=Pepe; expires=Tue, 3 Mar 2009 18:24:41 GMT; secure
• Si el dominio es m i p a g i n a .com, la cookie tambie ;c o m p r a = l e c h e ,p a n ,m a n z a n a s ; s e c u r e
se enviará, por ejemplo, a buscador .mipagina.
com, f o r o .m i p agina.com y, por supuesto, a mi- Esta delimitación sólo va a ser visual para nosotros a la hora
pagina.com. de escribir varias cookies seguidas. JavaScript puede manejar
• Si el dominio es w w w .m i p agina.com, la cookie no cada cookie de forma independiente aunque vayan todos los
se m andará a los subdomiruos. campos seguidos sin ese espacio en blanco, ya que es capaz
• p a t t r Funciona de m anera sim ilar a d o m a in , pero de detectar las palabras especiales pertenecientes a campos
especificando la ruta dentro del servidor donde sera opcionales.
enviada la cookie. Si no se añade este campo, se toma la
ruta de la página actual. 11.1.2. Almacenar una cookie
• Si el dominio es mi p a g i n a .com y la ruta es /ca
pitulos, la cookie tam bién se enviará, por ejemplo, Como ya hemos avanzado, JavaScript almacena las cookies
a b u s cador.mipagina.com/capitulos,mipa- dentro del objeto document, concretamente en su propiedad
g i n a .com/capitulos o m i p a g i n a .com/capi cookie. Por tanto, lo único que tendremos que hacer es cons­
tulos/JavaScript/. truir una cadena que contenga un estructura de cookie, es decir,
• Si el dominio es w w w .m i p a g i n a .com y la ruta / pares campo=valor y separados por punto y coma ( ;) . Para
capitulos, la cookie se mandará a www .mipagina^ facilitamos este trabajo, nos crearemos una función que luego
com/capitulos o www.mipagina.com/capi podremos reutilizar donde queramos. Esta función recibirá
tulos/JavaScript. , , como parámetros cada uno de los posibles campos que pueden
• Si la ruta es / entonces la cookie se envía por todo el formar la cookie y los irá concatenando si es necesario.
dominio. , . ___ • SCRIPT TYPE="text/javascript ">
• secure: Si este cam po está incluido en la c o o k i e en­ function almacenarCookie(nombre, valor, caducidad,
tonces ésta sólo se envía al servidor si la conexion se dominio, ruta, segura) {
ha establecido a través de un protocolo seguro, como var cookie;

267
// Añadimos el nombre de Xa cookie y su valor [Aplicación Ja va S c rip t]
cookie = nombre + "=" + escape(valor);
// Comprobamos si hemos recibido caducidad
if (arguments[2] != undefined) {
cookie += expires=” + caducidad.toGMTString0 ;
1 . .
// Comprobamos si hemos recibido dominio
Figura 11.3. Colección de cookies almacenadas en JavaScript.
if (arguments[3] != undefined) {
cookie += "; domain=" + dominio;
} ¿Ha visto? Sólo puede ver los pares nom bre=valor de cada
// Comprobamos si hemos recibido ruta cookie que haya almacenada (dos en nuestro caso). Esto no nos
if (arguments[4] != undefined) (
supone ningún problema, puesto que los otros campos los
cookie += "; path=" + ruta;
gestionará el navegador para detectar cuándo caduca, y por
// Comprobamos si hemos recibido segura y si hay tanto borrar la cookie, o saber a qué dominio o ruta pertenecen.
// que añadirla Además puede ver sustituido el carácter coma ( , ) por su equi­
if (arguments[51 != undefined && segura) í valente UNICODE (%2 C) ya que ese carácter no está permitido
cookie += "; secure"; como valor de la cookie.
} Recapitulando, para leer el valor de una cookie en con­
// Añadimos la cookie creto tendrem os que encontrar el par nom bre=valor que
document.cookie = cookie;
nos interese dentro de la propiedad d o c u m e n t. c o o k i e , la
} cual verem os com o una única cadena con todas las cookies
</SCRIPT>
concatenadas, así que necesitarem os usar las funciones de
Viendo este código podría pensar que al guardar una cookie búsqueda de las cadenas. Lo m ejor en este caso, al igual que
se sobrescribe el contenido completo de la propiedad c o o k ie para alm acenar una cookie, será crearnos una función que
ya que no se añade el valor (operadores + o +=), sino que di­ nos perm ita obtener cualquier cookie indicando únicam ente
rectamente se realiza una asignación (operador =). El ejemplo su nombre.
es correcto y no debe preocuparse puesto que JavaScript es el Lo primero que debemos com probar es si tenemos alguna
que se encarga de concatenar cada una de las cookies que aña cookie almacenada para evitar lanzar una búsqueda que sa­
damos a la propiedad de docum ent. bemos que no va a devolver nada.
// Comprobar si hay cookies
Nota: Si el nombre de una cookie ya existe, no se crea una
If (document.cookies.length > 0 ) {
nueva sino que se reemplaza su valor con el nuevo.___________ // Buscar y devolver el valor de la cookie
I else {
// Devolver un valor vacío
11.1.3. Recuperar una cookie return
I
Al contrario de lo que pueda pensar, cuando obtenemos
la información de una cookie que está almacenada en el objeto En caso de tener alguna cookie almacenada, debemos loca-
d o cu m en t, únicam ente podrem os extraer su valor, por lo Ii/ar en qué posición de la concatenación de cookies se encuentra
que todo lo referente a los campos opcionales quedará oculto. 1.1 que nos interesa. Esto lo harémos buscando por el nombre
Esto lo puede comprobar rápidam ente si intenta mostrar las de la misma.
cookies guardadas: Además comprobaremos si hemos encontrado esa posición
uno, para detener de nuevo la búsqueda. Si hemos encontrado
<SCRIPT TYPE="text/j avascript">
// Mostramos las cookies
1.1 cookie entonces calculamos la posición dónde com ienza el
a l e r t ( d o c u m e n t.c ookie); valor de la misma, que será a continuación del carácter = del
</SCRIPT> par nombre=valor.

268 269
■SCRIPT TYPE="text/javascript">
function recuperarCookie(nombreCookie) {
// Definición de variables
var posicionCookie, posicionPuntoComa;
/ / S i hemos encontrado la posición
var posicionlnicio, posicionFin;
if (posicionCookie != _D f ... „ ai„r var valorCookie =
// calculamos la posición de inicio del valor
posición!nicio = posicionCookie + nombreCookie. // Comprobamos si hay cookies
if (document.cookie.length > 0 ) {
length + 1 ;
// Buscamos la posición de la cookie
// Obtener valor de la cookie
posicionCookie = document.cookie.
indexOf(nombreCookie + "=");
/ / S i hemos encontrado la posición
if (posicionCookie != -1) {
// Calculamos la posición de inicio
// del valor
posicionlnicio = posicionCookie +
de la más nombreCookie.length + 1 ;
// Buscamos la posición del punto y
D ^ em o s t o e r ^ n ^ m t a la posibilidad de que no // coma más próximo
posicionPuntoComa = document.cookie.
¡ ^ S ^ pS 2 Í S S S ^ ^ í - « j * indexOf(";", posicionCookie);
inicio hasta el final del string que forma d o cu m en t. c o o k ie . / / S i estamos en la última cookie (no híi
// punto y coma)
// Buscar la posición del punto y c o m a más próximo
if (posicionPuntoComa == -1) {
posicionPuntoComa = document.cookie.indexO , ,
// Leemos hasta el final de la cadena
posicionFin — document.cookie.length;
r .t » c í '» i. « a - « o - 1* '» > ■ « >■” ” 1 co“ ’ ) else {
if (posicionPuntoComa — D i // En otro caso, leemos hasta el punt
// Leemos hasta el final de la cadena / / y coma
posicionFin = document.cookie.length,
posicionFin = posicionPuntoComa;
}
/ / E n otro caso, leemos hasta el punto y coma
// Obtenemos el valor de la cookie
posicionFin = posicionPuntoComa;
valorCookie = document.cookie.
substring(posicionlnicio, posicionFin);
Nos está quedando bien la función... Vamos con el ultimo }
oaso “ devolver e? valor de la cookie que buscamos! Esto , re- }
cuitará bastante sencillo // Devolvemos el valor de la cookie
suitara bastante sencu gracias
g a todo el trabajo previo que
de la cadena que return unescape(valorCookie);
1
i/:;c r i p t >

tuimos al almacenar la cookie. [A p licació n Ja v a S c r ip t ]

// Devolver el valor de la cookie


^usuarjo=Pepei_compra=leGhe%2Cpan%2Cman2anas
return unescape(document.cookie.
substring(posicionlnicio, posicionFin)), posicionCook¡«^''| posicionPuntoCom a
Ahora queyahemosexphcadotodoslos pasos,veam ostodo posicionlnicio

Figura 11.4. Representación visual de las posiciones


de una cookie.
necesario para lograr nuestro objetivo.

270
11.1.4. Modificar una cookie 11.2. Ejemplos prácticos
Aunque ya avanzam os algo hace un par de apartados, Para comprender todas estas funciones y acciones que se
modificar los campos de una cookie resulta bastante sencillo han explicado, vamos a desarrollar unos pequeños ejemplos
puesto que no necesitamos buscarla previamente dentro de utilizando formularios y código JavaScript para que sean más
la colección sino que será suficiente con volver a almacenarla cómodos de probar.
con los nuevos valores. El único requisito, lógicamente, es que
la cookie ya exista en la colección. , .,
Esto quiere decir que con volver a usar nuestra función 11.2.1. Almacenar y recuperar una cookie
a l m a c e n a r C o o k i e , junto con los nuevos valores y el mismo
Estas son las acciones más básicas y comunes que se pueden
nombre de cookie, habrem os modificado todos los campos que
apkcar sobre las cookies. Para comprobarlo por nosotros mismos,
hayam os indicado. Cuidado con esto porque en caso de usar
crearemos un sencillo formulario que nos permita añadir co­
un nombre de cookie que no esté en la coleccion almacena­
okies que constará de varias cajas de texto para introducir los
remos una nueva. valores y un botón para añadirla a la colección de cookies del
<SCRIPT TYPE="text/javascript"> navegador.
// Creamos una cookie <HTML>
almacenarCookie("compra", "leche,pan,manzanas );
<BODY>
// Modificamos la cookie
<H3>Formulario para añadir cookies</H3>
almacenarCookie("compra",
<FORM ID="formulariol" NAME="formCookie">
"leche,pan,manzanas,queso");
Nombre de la cookie: <INPUT TYPE="text" ID="entradal"
</SCRIPT> NAME="nombre" /> <B> (obligatorio) < / B X B R />
Así da gusto, ¿verdad? Las funciones que estamos creando Valor: <INPÜT TYPE="text" ID=”entrada2" NAME="valor" />
<B> (obligatorio) < / B X B R />
nos van a ser de mucha utilidad para dar una claridad tre­
<INPUT TYPE="button" ID="botonl" NAME="botonAgregar"
menda a nuestro código. VALUE="Agregar" ONCLICK="agregarCookie()" />
<INPUT TYPE="button" ID="boton2" NAME="botonLeer"
VALUE="Leer" ONCLICK="leerCookie()" / >
11.1.5. Borrar una cookie </FORM>
•:/BODY>
Por suerte para nosotros, borrar una cookie resulta tan sen­ •:/HTML>
cillo como modificarla. En concreto tendremos que cambiar
su fecha de caducidad haciendo que no sea valida a partir Formulario para añadir cookies
del m omento actual. La fecha que debemos fijar tiene que ser
igual o anterior a la fecha y hora actuales. Lo mas sencillo es Nombre de la cookie: [ J (obligatorio)
usar la hora actual, ya que la cookie se invalidara en el siguiente Valor: ] (obligatorio)
milisegundo. | Agregar |[ Leer |

<SCRIPT TYPE="text/ javascript">


Figura 11.5. Formulario para administrar cookies.
// Creamos una cookie
almacenarCookie("usuario", "Pepe");
// Borramos la cookie Por supuesto, también tendremos que definir la función
almacenarCookie("usuario", "Pepe", new Da t e ()); .isociada al manejador ONCLICK del botón Agregar, que no
</SCRIPT> luirá otra cosa que leer los datos que hemos escrito en el for­
Tras hacer esto, el navegador detectará que la cookie ha ca­ mulario y llamar a la función almacenarCookie que hemos
ducado, la borrará de la colección y ya no será recuperable. creado en el apartado anterior.

273
valorCookie = recuperarCookie(nombreCookie);
<SCRIPT TYPE="text/javascript"> }
function agregarCookie() {
// Mostramos el valor de la cookie
// obtenemos los campos if (valorCookie != "") {
with (document.formCookie) {
alert("El valor de la cookie " + nombreCookie +
// Comprobamos si hemos indicado el nombre
" es:\n" + valorCookie);
// y valor } else {
if (nombre.valué == "" II valor.valué — ) {
alert("Debe escribir el nombre y valor alert("No se ha encontrado la cookie " +
nombreCookie);
de la cookie.") ;
}
nombre.focus ();
}
return; </SCRIPT>
} else { .■
// llamamos a la función que crea la cookie Bueno, pues después de tanto código llega el momento de
a l m a c e n a r C o o k i e (nombre.valué, valor.valué);
probarlo (cruce los dedos). Le invito a recrear los siguientes
alert("Cookie " + nombre.valué +
casos en su ordenador:
" almacenada.");
) 1. Recuperar una cookie sin haber alm acenado ninguna.
D ebe aparecer un m ensaje indicando que no se ha
} encontrado una cookie con ese nombre.
</SCRIPT>
2. Alm acenar una cookie con un nom bre de usuario. La
C om o ve, esta función no tiene m ucha com plicación. cookie se almacenará en la colección.
Solamente hem os ido comprobando cada vino de los campos 3. Recuperar la cookie con el nom bre de usuario. Debe
del formulario para saber si teman algo escrito y mostrar aparecer un mensaje con el valor de la cookie.
mensaje al usuario en caso contrario, dejando el foco en la caja 4. Modificar el valor de la cookie con el nombre de usuario.
de texto correspondiente al nombre de la cookie. La cookie se almacenará en la colección.
En cuanto a recuperar los valores de las cookies nos ten­ 5. Recuperar la cookie con el nom bre de usuario. Debe
dremos que construir otra función (leerCookie), para aso­ aparecer un mensaje con el nuevo valor de la cookie.
ciarla al manejador ONCLICK del botón Leer, que se encargara
de mostrarnos el valor de la cookie cuyo nombre coincida con
el que esté escrito en el formulario. Aquí usaremos nuestra 11.2.2. Expiración de cookies
magnífica función r e c u p e r a r C o o k i e .
Tomando com o base el caso anterior, vam os a añadir un
CSCRIPT TYPE="text/javascript"> campo m ás al form ulario para poder indicar cuándo que­
function leerCookie0 {
remos que caduque o expire nuestra cookie, expresado en
var nombreCookie;
segundos.
var valorCookie = "",*
// Obtenemos el nombre ■MTML>
with ( d o c u m e n t . formCookie) l •BODY>
// Comprobamos si hemos indicado el no re •H3>Formulario para expiración de cookies</H3>
if (nombre .valué == '"') ( •FORM ID="formulariol" NAME="formCookie">
alert("Debe escribir el nombre Nombre de la cookie: CINPUT TYPE="text" ID="entradal"
de la cookie."); MAME="nombre" /> <B> (obligatorio) C / B X B R />
nombre.focus(); Valor: <INPUT TYPE="text" ID="entrada2" NAME="valor" />
return; •B> (obligatorio) C / B X B R />
} else { . Caducidad: CINPUT TYPE="text" ID="entrada3"
// Guardamos el nombre de la cookie NAME="caducidad" /> (segundos)CBR />
nombreCookie = nombre.valué; •INPUT TYPE="button" ID=”botonl" NAME="botonAgregar"
VALUE="Agregar" ONCLICK="agregarCookie()" />
) / Llamamos a la función que recupera la cookie

275
274
<INPUT T Y P E = " b u t t o n " ID-"boton2" ÑAME botonleer En el cálculo de la fecha de caducidad hay un pequeño
VALUE="Leer" ONCLICK="leerCookie()" /> detalle que explicar ya que es posible que le resulte extraña
</FORM> esa m ultiplicación por mil. En realidad lo que se ha hecho es
</BODY> guardar la fecha en forma de m ilisegundos. Para ello, hemos
</HTML> transformado la fecha y hora actuales en esa unidad mediante
el método getTime y le hemos sumado el número de segundos
Formulario para añadir cookies indicados en el formulario, también expresado en milisegundos
(de ahí la multiplicación).
|(obligatorio)
Nombre de la cookie. I Con este ejemplo podremos intentar crear dos cookies con
"H (obligatorio) distintas fechas de caducidad:
|
|(segundos)
Caducidad: 1 1. Para la primera (de nombre cookie_sesion) no indi­
[ Aqregar 11Leer j ---------------------- caremos una cantidad de segundos como caducidad, por
Figura 11.6. Formulario para administrar cookies. lo que expirará cuando cerremos la ventana del nave
gador. Esto significa que seremos capaces de recuperar
su valor siempre y cuando no cerremos el navegador.
Del mismo modo, debemos añadir unas líneas a la función Una vez que lo hagamos, la cookie habrá expirado y no
del manejador ONCLICK del botón A gregar para poder a m - permanecerá en la colección.
t ^ T c o o k i e con la caducidad que hayam os indicado en el
2. A la segunda (de nom bre cookie_minuto) le pon
formulario. dremos 60 segundos como tiempo de expiración, así que
<SCRIPT TYPE="text/javascr ipt"> podremos obtener su valor durante el siguiente minuto
function agregarCookie() { aunque cerremos el navegador. Pasado ese tiempo la
var expiración; cookie expirará.
var hoy = new Date() ;
// Obtenemos los campos Por último, sólo destacar que aunque únicamente calcu­
with ( d o c u m e n t . formCookie) { lemos la fecha de caducidad cuando se ha introducido un valor
b
// comprobamos si hemos indicado el nombre en el formulario, siempre se pasa la variable expiración
// y valor ____ " "I I valor.valué == "")( como parámetro a la función almacenarCookie ya que, si no
if (nombre.valué — II
alert("Debe escribir el nombre y valor Ilemos realizado el cálculo, su valor será undefined y proven a
de la cookie.");
i|ue no se añada ese parámetro opcional a la cookie.
nombre.focus();
return;
11.2.3. Modificar una cookie
// comprobamos si hemos indicado caducidad
if (caducidad.valué != "") í Para probar esta funcionalidad podemos utilizar el formu
expiración = new Date(), lario y las funciones JavaScript asociadas a él de los ejemplos
expiración.setTime(hoy.getTime() + .interiores, puesto que la m odificación de una cookie equivale
( c a d u c i d a d .v a l u é * 1 0 0 0 ) ) ; .i volver a almacenarla y el procedimiento de recuperación de
mi valor no varía. Realizaremos las siguientes operaciones para
// Llamamos a la función que crea la cookie
almacenarCookie(nombre.valué, valor.valué,
ver cómo funciona la modificación de una cookie:
expiración); 1. Creamos una cookie y a continuación recuperam os su
alert("Cookie " + nombre.valué + valor. A hora m odificarem os su valor ("cream os" la
" a l m a cenada.") ; misma cookie con el nuevo valor) y volvem os a recu­
perarla para com probar que el cam bio se ha hecho
} efectivo.
</SCRIPT>

277
276
2. C ream os una cookie sin indicar fecha de caducidad
(expirará al cerrar el navegador). Seguidam ente m o­
dificamos su fecha de caducidad a 60 segundos, por
ejemplo. Entonces si cerramos el navegador e intentamos
recuperar la cookie veremos su valor. Pasado ese tiempo,
la cookie no debería seguir estando accesible.

11.2.4. Borrar una cookie


Por último, vamos a comprobar lo fácil que resulta eliminar
una cookie de la colección usando el mismo formulario y código
JavaScript que hasta ahora.
Para refrescarle la memoria, una cookie se borrará cuando
haya expirado, es decir, cuando su fecha de caducidad sea
anterior a la fecha actual. Como en nuestro formulario no in­
dicamos una fecha concreta sino un plazo en segundos, bastará
con poner un valor igual o menor a cero. El cero representa la
hora actual (la cookie expira en el siguiente m ilisegundo) y los
negativos indican una hora anterior a la actual (hace 3 ,1 0 ó 60
segundos por ejemplo).
Por tanto, el ejemplo que nos ocupa consistirá en crear una
nueva cookie y, tras comprobar que podemos recuperar su valor,
modificaremos su caducidad con un valor -5 (o el primero que
piense, pero siempre menor o igual que cero). Si a continuación
intentamos recuperar el valor de esta cookie nos encontraremos
con que ésta ha sido borrada.
Si queremos rizar el rizo, podríamos hacer una pequeña
variación en la función agregarCookie para que nos in­
dique cuándo borramos una cookie. Esto se puede hacer muy
rápidamente si nos fijamos en el valor del cam po caducidad
del formulario: si no es vacío, y su valor es menor o igual a
cero, entonces estamos borrando. En otro caso, la cookie se está
almacenando.
// Llamamos a la función que crea la cookie
almacenarCookie(nombre.valué, valor.valué, expiración); I
if (caducidad.valué != "" && caducidad.valué <= 0) {
alert("Cookie " + nombre.valué + " borrada.");
} else {
alert("Cookie " + nombre.valué + " almacenada.");
)
Como ve, rápido, sencillo y para toda la familia.

278
12
Ejemplos prácticos

Este capítulo presenta una serie de ejercicios que intentan


poner en práctica los diversos conocimientos que habrá ad­
quirido con este libro. Aunque todos estos scripts vienen expli­
cados y con su solución (que no la única, ya que siempre hay
varias formas de llegar a lo mismo), le recomiendo que antes
de mirarla intente pensar por su cuenta cóm o lo resolvería, o
al menos qué funciones u objetos harían falta para conseguir
llegar al objetivo.
Sin más, le dejo que disfrute de nueve útiles ejemplos.

12.1. Mostrar un texto rotativo


Como primer ejemplo práctico vamos a simular el efecto de
la etiqueta HTML <MARQUEE> (bastante obsoleta, por cierto)
que consiste en mostrar un texto desplazándolo horizontal­
mente hacia la izquierda a modo de letrero informativo.
Los elementos que vamos a utilizar para crear este efecto
son:
1. Una capa HTML que contendrá el mensaje.
2. Una función JavaScript que hará rotar el texto.
La capa HTML será muy sencilla y únicamente le fijaremos
una anchura y un borde. El motivo de fijar estos dos atributos
será para que el efecto se aprecie aunque el texto a rotar sea
corto. Además, también centraremos el texto en la capa para
i|ue quede más bonito. No se preocupe si no conoce el len­
guaje HTM L a fondo, aquí va una ayuda de cómo debe estar
definida la capa:

279
<DIV ID="capaTexto" STYLE="border: Ipx solid #000000; Para que el texto comience a desplazarse nada más cargar
width: 250px; text-align: center">El texto que queramos la página, asociarem os esta función al manejador ÜNLOAI) del
desplazar</DIV> documento.
Seguidamente definiremos la función JavaScript que creará <BODY ONLOAD="arrancarRotativo()">
el efecto rotativo, cuyo m ecanismo será el siguiente:
P u es b ien , ¡ya ten em o s p re p arad o n u estro p rim er
• Recoger el texto que hay dentro de la capa para saber ejemplo!
cuál es. Esto es posible gracias a la propiedad inner­
HTML, que ya hemos explicado para objetos como an­ [ H tentó que queramos desplazar ||- - - - - - - - j^ > [ o qut g u a m o s desplazara text |l ^ >| ~ despkarEI texto que g ro m o s |
chor (ancla). Para acceder a la capa nos apoyaremos en
el m étodo getElementByld del objeto document. Figura 12.1. Efecto de texto rotativo.
• Trasladar el prim er carácter del texto al final, para
sim ular que se ha desplazado una posición a la iz­ Para hacer un poco más útil este texto rotativo, vamos a
quierda. hacer que el efecto cese cuando pongamos el ratón encima de la
• Escribir el nuevo texto en la capa. capa, para poder leer el texto más cóm odamente, y se reanude
Con todo esto escribiremos la función que "dará vida a cuando lo quitemos. ¿Le suena difícil? ¡En absoluto! Ya verá
nuestro texto. que con cuatro pinceladas vamos a aumentar la funcionalidad
de este rotativo.
function d e s p l a z a r Texto() {
Lo primero es escribir una función que detenga el tem ­
// Obtenemos el texto de la capa
var texto = d o c u m e n t .getElementByld("capaTexto") . porizador que lanza continuam ente el desplazam iento del
innerHTML; texto. Para ello nos hace falta conocer su identificador, así que
// Trasladamos el primer carácter al final tendremos que crear una variable global y guardar en ella el
texto = texto.substring(1, texto.length) + texto. resultado de la ejecución de setlnterval.
substring(0, 1) ; // Variable global
// Escribimos el nuevo texto
document.getElementByld("capaTexto").innerHTML — texto, var temporizador;
function a r r a n c arRotativo() {
} // Fijamos el temporizador
Por último, necesitam os fijar un temporizador que ejecute temporizador = setln t e r v a l ("despla z a r T e x t o ()", 150);
repetidamente la función anterior para así crear el efecto de­
seado. Tenemos dos opciones: Ahora que ya tenemos lo necesario para detener el efecto,
• setTimeout: Nos ejecutará una única vez la expresión vamos a escribir la función de parada.
que le indiquemos. function detenerR o t a t i v o () (
• setlnterval: Nos ejecutará continuamente la expre­ // Detenemos el temporizador
sión indicada. clearlnterval(temporizador);
}
Lo vemos claro, ¿no? Nos conviene usar la función setln­
terval para arrancar de una sola vez el efecto del rotativo. En ¿Le parece que falta algo? Efectivamente, ya sólo queda
función del intervalo de tiempo que fijemos, el texto parecerá incluir en la capa los manejadores correspondientes a los movi­
que se mueve más lento o más deprisa. Un valor medio pueden mientos del ratón para que se lancen las funciones oportunas
ser 150 milisegundos. ¡y tendremos todo listo para probar!

function a r r a n c a r Rotativo() { <DIV ID="capaTexto" STYLE="border : lpx solid #000000;


I I Fijamos el temporizador width: 250px; text-align: center" ONMOUSEOVER=
setlnterval("desplazarTexto 0 ", 150); "detenerRotativo()" ONMOUSEOUT="arrancarRotativo()">E1
texto que queramos desplazar</DIV>
)

280 281
// Extraemos la letra calculada
12.2. Calcular la letra del DNI letra = letrasDNI.substr(posicion, 1);
// Devolvemos la letra
Gracias a este ejemplo seremos capaces de calcular automa return letra;
ticamente la letra de un DNI. Si utilizamos esto dentro de un }
formulario, podrem os saber si el usuario ha introducido bien Puesto que este cálculo se realizará cuando presionemos el
su DNI o si le hem os cazado mintiendo. botón V alidar del formulario, debemos crear otra función para
Primeramente nos crearemos un pequeño formulario, par asociarla a su manejador ONCLICK. Esta función recogerá el
recoger elvalor escrito por el usuario, que constara de una caja valor introducido en la caja de texto, que le eliminará la letra y
de texto y un botón que lanzará la operacion de validación. llamará a la función calcularLetra con el valor resultante.
Vayamos paso a paso.
<H3>Formulario para validar un DNI</H3>
Crearemos dos funciones: una para comprobar el formato
<FORM ID="forraulariol" NAME="formDNI">
DNI: <INPüT TYPE="text" ID="entradal" ÑAME- d m del DNI introducido mediante un patrón y a la vez desechar la
MAXLENGTH="9" /> letra que contenga, y otra función, para asociarla al manejador,
<INPUT TYPE="button" ID="botonl" ÑAME- botonValidar que nos dirá si la letra es correcta.
VALUE="Validar" /> La prim era función com probará antes de nada que el DNI
</FORM> tiene un form ato válido. Para realizar este proceso usarem os
uno de los patrones que m ostram os en el apartado 2.4 del
Formulario pai'a validar un DNI capítulo 2: / \ d {8 } [a-zA-Z] /. Si se supera esta pequeña
prueba, entonces separarem os la letra del DN I (que está
DHtl |r VaüdarJ justo al final del todo) y devolverem os el resto del número
para su posterior validación. En otro caso, m ostrarem os un
Figura 12.2. Formulario para validar un DNI. mensaje al usuario para advertirle que el DNI introducido
no es válido.
Ahora definimos la función que calcula la letra que le co­ function comprobarFormato(numeroDNI) {
rresponde a un número de DNI. Esta función es publica asi // Declaración de variables
que no crea que acabo de piratear nada:). Su funcionamiento var patronDNI = new RegExp("\\d(8)[a-zA-Z]");
// Comprobamos el formato
es m u y simple: if (patronDNI.test(numeroDNI)) {
. Se dispone de una lista de 24 letras (de la A a la Z) // Devolvemos los 8 números del DNI
almacenadas en un string. , , _ return numeroDNI.substr(0, 8);
. Para saber qué letra le corresponde a cada numero, se } else {
I I Mostramos un mensaje al usuario
calcula una posición a partir del numero de DNI apli­ alert("El DNI " + numeroDNI + " no tiene un
cando el m ódulo sobre 23 ( númer o _d ni % 2. 3 ). formato válido");
• Se extrae la letra que está en la posición calculada ante­ return "";
riormente. }
)
Veam o s esto ahora expresado en forma de codigo
Ahora vamos con la función que vamos a asociar al mane-
JavaScript:
jador del botón Validar. Lo que tendrá que hacer es comprobar
function calcularLetra(numeroDNI) { i|ue el DNI introducido es válido, mediante la función com-
// Declaración de variables probarFormato, y después comparar la letra introducida con
var posicion, letra; „„„„
var letrasDNI = "TRWAGMYFPDXBNJZSQVHLCKET ; l.i calculada en la función calcularLetra. Si ambas coinciden
// Calculamos la posición entonces se informa al usuario de que su DNI es correcto, y de
posicion — numeroDNI % 23, lo contrario si no coinciden.

283
282
<H3>Hora actual</H3>
function v a l i d a r D N I O {
// Declaración de variables <FORM ID= "formulariol" NAME="formHor.i"
var DNIUsuario, numeroDNI, letraUsuario, letraCalculada, CINPUT TYPE="text" ID="entradal" NAMK "I... i , .i
// Recogemos el valor del formulario SIZE="2" READONLY /> :
DNIÜsuario = d o c u m e n t .formDNI.dni.valué; <INPUT TYPE="text" ID="entrada2" NAME-"ml nA< i 114 I"
// Comprobamos el formato y guardamos el número SIZE="2" READONLY /> :
CINPUT TYPE="text" ID="entrada3" NAMU " in„i"
// sin la letra
numeroDNI = comprobarFormato(DNIUsuario); SIZE="2" READONLY />
C/FORM>CBR />
// Si el formato es correcto
CH3>AlarmaC/H3>
if (numeroDNI != "") {
// Guardamos la letra introducida por el usuario CFORM ID="formulario2" NAME="formAlarm.i" •
letraUsuario = DNIUsuario.substr(— 1); CINPUT TYPE="text" ID="entrada4 " NAME~"hui .iA 1 .11111.1"
SIZE="2" /> :
I I Calculamos la letra por nuestra cuenta
letraCalculada — calcularLetra(numeroDNI); CINPUT TYPE="text" ID="entrada5" ÑAME-"mi tiAI <1 1111.1 "
// Comparamos ambas letras mostrando un mensaje SIZE="2" />
if (letraUsuario.toUpperCase() == letraCalculada) { CINPUT TYPE= "button" ID="botonl" NAME-"bot 011A1 I l - n "
alert("El DNI " + DNIUsuario + " es correcto"); VALUE="Activar" />
CINPUT TYPE= "button" ID="boton2" NAME="botaiiln-,.i, l | ("
) else {
alert ("La letra del DNI " + DNIUsuario + VALUE="Desactivar" />
c/FORM> /
" no es correcta");
}
} Hora actual
)
Para terminar este ejemplo tan sólo queda asociar la función
v a l i d a r D N I al manejador O N C L I C K del botón del formulario
y ya habremos terminado todo el trabajo.
<INPUT TYPE="button" ID="botonl" NAME="botonValidar Alaima
VALUE="Validar" ONCLICK="validarDNI ()"/>
¡ | | | | Activar 11 Desactivar 1

Figura 12.3. Aspecto de nuestro reloj despertador.


12.3. Un reloj despertador
También incluiremos una simpática imagen (alarma.jpg)
Creo que todos conocemos estos simpáticos artilugios que
que sólo será mostrada cuando salte la alarma, de forma que
se encargan de recordarnos todas las m añanas (de mejor o
quedará algo más vistoso que con un simple mensaje. En el
peor manera) que tenem os que resoplar y hacer un esfuerzo
momento de cargar la página no mostrarem os nada para no
por salir de esa mullida "prisión" en forma de cama (qué poé­
revelar lo que está por llegar;).
tico ha quedado, ¿no?). En resumidas cuentas, el reloj desper­
tador que nos vamos a construir en JavaScript se encargara de <IMG ID="imagenl" NAME="imagenAlarma" SRC="" />
hacer saltar una alarma (silenciosa, por suerte para nosotros)
A continuación vamos a crearnos una función JavaScript
cuando la hora actual sea la misma que la que hayamos fijado
que muestre la hora actual en su formulario correspondiente,
para tal fin. . para lo cual tendremos rellenar los tres campos con las horas,
Para hacer las cosas paso a paso, vam os a incluir primero minutos y segundos respectivamente.
un par de formularios en la página: uno para mostrar la hora
actual y así saber cuándo va a llegar el m omento que todos lunction m o s t r a r H o r a () {
// Obtenemos la fecha y hora actuales
tememos, y otro para fijar la hora de la alarm a y activarla o
var ahora = new D a t e ();
desactivarla.

284 285
if (alarma != undefined) {
// Colocamos los valores necesarios en el formularlo
// Si coincide la hora actual con la alarma
with(document.formHora){ if (ahora.getHours () == alarma.getHours() &&
horaActual.valué = a h o r a .getHours();
ahora.getMinutes() == alarma.getMinutes()) {
minActual.valué = a h o r a . getMinutes();
// Mostramos la imagen
segActual.valué = a h o r a .g e t S e c o n d s (),
document.imagenAlarma.src = "alarma.jpg";
} } else {
} // En otro caso, volvemos a comprobar en 1 minuto
Adem ás, com o querem os que la hora se actualice para idComprobarAlarma =
setTimeout("comprobarAlarma()", 60000);
tener siem pre la referencia en la pantalla, incluirem os un
}
temporizador ( s e t l n t e r v a l ) que se ejecute continuamente ¡
cada segundo. Esta sentencia la podemos situar bien dentro }
del manejador ONLOAD del documento o simplemente dentro
de una etiqueta <SCRIPT> al final del todo. En este ejemplo Ahora llega el tum o de crear la función que fija la alarma
seguiremos la primera opción por comodidad: con la hora y minutos que digamos. Como la alarma debe saltar
justo cuando se cambia de minuto (pasamos del segundo 59 al
<BODY ONLOAD="setlnterval('mostrarHora()', 1000), > 00) no podemos hacer la primera comprobación para dentro de
Antes de almacenar y activar la alarma, le quiero comentar un minuto a partir de la hora actual, ya que tenemos pocas pro­
que en nuestro código tendremos declarada una variable de babilidades de estar en el segundo 00. Para Solucionar esto, lo
ámbito global ( a l a r m a ) que se encargará de guardar la hora que haremos es calcular la diferencia entre los segundos actuales
a la que debe saltar la alarma. Dicho esto, sigamos declarando y 60 (que representa el comienzo del siguiente minuto). De este
modo programaremos la primera comprobación para dentro de
fUnAhora es el tum o de crear una que compruebe si debe saltar esa cantidad de segundos pero expresada en milisegundos, ya
la alarma, es decir, si la hora actual coincide con la fijada como que es la unidad que maneja s e t T i m e o u t . Y ya que estamos,
alarma. Esta com probación puede hacerse de varias maneras, para rematar la función, dejaremos vacío el atributo SRC de la
imagen de alarma, después de fijar la hora y minutos, para evitar
pero dos de ellas serían:
que esté visible después de haber saltado una alarma anterior.
1. Obtener la hora actual mediante el objeto D a t e y com­
function fijarAlarma(hora, minutos) {
pararla con la fijada en la variable a l a r m a .
// Declaración de variables
2. Obtener la hora actual desde el formulario for mHora
var ahora, primeraComprobacion;
y compararla con la fijada en a l a r m a . // Fijamos la alarma
alarma = new Da t e ();
Ambas son válidas y las diferencias en el código no son
alarma.setHours(hora, minutos);
muy grandes. N osotros seguiremos la prim era opcion, por
// Preparamos la primera comprobación de alarma
decir alguna. ahora = new Date();
Si la hora actual hace que salte la alarma, entonces mos­ primeraComprobacion = (60 - ahora.getSeconds()) *
traremos nuestra imagen sorpresa al usuario modificando el 1000;
atributo SRC de imagenAlarma. En otro caso, debemos forzar idComprobarAlarma = setTimeout("comprobarAlarma()",
que se vuelva a realizar la comprobación un minuto despues (60 primeraComprobacion);
// Dejamos de mostrar la imagen de alarma
segundos = 60000 milisegundos) mediante el uso del método
document.imagenAlarma.src =
s e t T i m e o u t , del que guardaremos su identificador en otra va­
}
riable global (idComprobarAlama). Veamos todo esto ]unto:

function comprobarAlarma() { Nota: Recuerde que el método s e t H o u r s acepta hasta cuatro


// Obtenemos la hora actual parámetros (horas, minutos, segundos y milisegundos), pero
var ahora = new DateO; sólo es obligatorio el primero.
/ / S i hay una alarma fijada

287
286
Seguid am ente nos ponem os 'm a n o s a la o b ra ' con la <INPUT TYPE="button" ID="botonl" NAMK "|...i . . , , ,,n
función que activa la alarma recogiendo los valores introdu­ VALUE="Activar" ONCLICK="activarAlarm«()"
CINPUT TYPE="button" ID="boton2" ÑAME "I>•,1 ..1 ,1 i¡ „■
cidos en el formulario para fijar la alarma. Además, antes de
VALUE="Desactivar" ONCLICK="desactiv;i iA I..iiim (l"
hacerlo, podem os aprovechar para establecer unos valores
por defecto a los dos campos del formulario por si alguno no
Hora actual
tuviese valor.
function a c t i v a r A l a r m a () { jl7 |: [37 |: ¡44
// Fijamos valores por defecto
var hora = 12, minutos = 00;
// Comprobamos los valores del formulario
w i t h ( d o c u m e n t .f ormAlarma){ Alalina
// Guardamos el valor de la hora, si está escrito
if (horaAlarma.valué != "") {
I” ~1:|39__ 11 Activar 1| Desactivar 1
hora = horaAlarma.valué;
Figura 12.4. Nuestra alarma fijada para dentro de poco.
//Guardamos el valor de los minutos, si está escrito
if (minAlarma.valué != "") {
minutos = m i n A l a r m a .v a l u é ; Hora actual
}
// Fijamos la alarma [17 |; [39 |; [0 |
fijarAlarma(hora, minutos);
}
)
Como hemos incluido en nuestro reloj despertador un botón Alanna
para poder desactivar la alarma antes de que ésta haya saltado,
debemos crear otra función para tal tarea. No nos resultará muy 1:!39 iI Activar || Desactivar |
complicada puesto que tan sólo debemos impedir que se siga
comprobando la alarma, utilizando el método c l e a r T i m e o u t
junto con el identificador i d C o m pr o ba rA l a rm a que hemos
ido guardando en las otras funciones. Asim ismo, debemos
borrar la hora fijada en la variable a l a r m a asignándole un
valor nulo (nuil). Aquí tam bién sera conveniente ocultar la
imagen de alarma puesto que no tiene sentido que aparezca
si no hay una alarma fijada.
function d e s a c t i v a r A l a r m a () {
// Dejamos de comprobar la alarma
clearTimeout(idComprobarAlarma);
// Borramos la hora fijada
alarma = nuil;
// Dejamos de mostrar la imagen de alarma
d o c u m e n t .i m a g e nAlarma.src = ""; Figura 12.5. ¡La alarma ha saltado!.
}
Para terminar ya con este ejemplo, sólo nos queda asociar Ya tenemos nuestro reloj despertador funcionando, pero
las funciones de activación y desactivación de la alarma al m a­ todavía lo podemos hacer más real. Si le nombro la palabra
nejador ONCLICK de los botones correspondientes. miooze, ¿le suena de algo? A los madrugadores quizá no, pero

288 289
para el resto es el botón más utilizado de todo el despertador y Hora actual
casi siempre va asociado a la frase "bueno, un ratito más y me
levanto". Efectivamente, se trata del botón que aplaza la alarma
para que suene unos minutos más tarde sin tener que fijar una
nueva hora. ¿Le parece si creamos esta nueva funcionalidad en
Alalina
nuestro script? Aunque no lo crea, resultará bastante sencillo [Aplicación J o v a S i t l|»l |
gracias a todo lo que ya tenem os hecho. liz __ j : l 46 ] [ Activar | [ Desactivar ]
Esta nueva opción en nuestro despertador debe pregun­ i c i nt l I K» |~-••«»>«•
tam os si queremos aplazar la alarma justo cuando ésta salte a la
hora program ada, por lo que sólo tendremos que modificar la
función c o m p r o b a r A l a r m a . Este cambio consistirá en lanzar
al usuario la propuesta de aplazar la alarma, a la que podra
responder afirmativa o negativamente. Si decide no aplazar
la alarma, entonces desactivaremos la actual, pero si pretiere
dormir un poco más entonces reprogramaremos la alarma au­
tomáticamente para dentro de un minuto (sí, soy consciente de
que es poco pero es sólo para probar el código). Para recoger
la respuesta del usuario usarem os el m étodo c o n f i r m para
después analizar el botón pulsado y actuar en consecuencia.
Allá vamos:
Figura 12.6. Pregunta para aplazar la alarma
function comprobarAlarma() {
// Obtenemos la hora actual
var ahora = new DateO; Después de todo lo expuesto, le dejo como e jm u in |mt s c mi.i I
/ / S i hay una alarma fijada que intente implementar un número máximo di'.ipl.iz.imienlos
if (alarma != undefined) { ile la alarma, es decir, que podamos hacer i|iu> sig.i salí,indo
/ / S i coincide la hora actual con la alarma
if {ahora.getHoursO == alarma.getHours () && Ja alarma durante una cantidad de minutos oxtr.i mediante
"snoozes".
ahora.getMinutes() == alarma.getMinutes0 ) (
// Mostramos la imagen
d o c u m e n t . imagenAlarma.src = "alarma.jpg";
/ / S i quiere aplazar la alarma
if (confirme¿Quiere dormir un rato más?")) { 12.4. Calcular los caracteres restantes
// Damos un minuto de tregua de un SMS
fijarAlarma(alarma.getHours(), alarma.
getMinutes () + 1) ;
} else { Estamos a punto de desarrollar un script cuya funciona­
/ / E n otro caso, desactivamos la alarma lidad le será muy fam iliar a muchos: calcular y m ostrar los
desactivarAlarma();
caracteres restantes de un texto, centrándonos en el caso de
} un SMS. H oy en día esto está presente en todos los móviles,
} else {
// En otro caso, volvemos a comprobar ■maque a veces muestran la cantidad restante cuando estamos
llegando al límite.
// en 1 minuto
idComprobarAlarma = 1 Comenzaremos por simular, sin ningún tipo de alardes, la
setTimeout("comprobarAlarma()", 60000); pantalla del móvil mediante una caja de texto (<TEXTAREA>)
> i|ue sea lo suficientemente grande para ver el texto completo;
} |><>rejemplo, tres filas (atributo ROWS) y unos sesenta caracteres
}

290 291
de ancho (atributo COLS). Debajo de ella situaremos otra caja // Declaración de constante
de texto (<INPUT>) en la que iremos actualizando la cantidad var LONGITUD_MAX = 160;
de caracteres que podemos incluir aún en nuestro mensaje. function calcularRestantea (I i..i |
// Calculamos los caractei c-i
Este cam po m ostrará inicialm ente el núm ero m áxim o de
var resto = LONGITUD_MAX - t > i i»i..il|ij
caracteres permitidos en un SM S, que es 160. Por supuesto, // Escribimos el resultado km . I i .»nt
ambas cajas deben ir dentro de un formulario para poder tra­ document.formSMS .longitud.v.i Iu> » <i U
bajar con ellas. }

N ota: A modo de curiosidad, los SMS tienen esta limitación Bien, ya tenemos todo casi prepai...I.. ...I............ . , i , ,.|
de longitud porque inicialmente se pensaron como mensajes de pequeño" detalle de saber cuándo ll.iin.u |.« i............ .,
control y no como un servicio añadido para el usuario final. cularRestantesparaquenosactu.ili.r.'l......... ,(,•
caso, el mejor lugar sin duda es dentro del in.tn. |.i. I............. mi
Siguiendo con nuestro ejemplo. El formulario nos quedará de la caja de texto sms. Gracias a esto, si* n .di h ( , |. ,i, ,,|M
bastante sencillo: cada vez que se suelte una tecla, bien sc.i p.u.i m ..I .. . ,,
teres o para borrarlos. Como tenemos ipiiMl....... , |, i,....... ..
<H3>Escriba su SMS</H3> sobre qué texto debe realizar la operación, r«n ........... |.,
<FORM ID="formulariol" NAME="formSMS">
CTEXTAREA ID="entradal" NAME="sms" ROWS="3"
sentencia t h i s para pasar el contenido de l.i. ,i |.i ii>i.r i. ,|.„|
COLS= "60 "></TEXTAREAXBR />
valué) como parámetro.
Quedan CINPUT TYPE="text" ID="entrada2" NAME="longitud"
<TEXTAREA ID="entradal" NAME="sms" ROW.'i " l" ..i| "..
SIZE="3" VALUE="160" READONLY> caracteres
ONKEYUP="calcularRestantes(this. valué)" •/TI > I ii
</FORM>

Escriba su SMS Escriba su SMS

H ola, e s t o y e s c r ib ie n d o un s c r i p t muy c h u lo . LueHn i r h,


e n señ o .

Quedan [96 caracteres


Quedan 160 ¡caracteres

Figura 12.7. Formulario para calcular los caracteres restantes Figura 12.8. Cálculo de los caracteres restantes de un SMS.
de un SMS.
Llegados a este punto, si nos ponemos a pensar por un mo­
En cuanto al código JavaScript, tendremos declarada una mento nos daremos cuenta de que este script está incompleto
constante (LONGITUDJV1AX) con el número máximo de ca­ ya que se muestra el núm ero de caracteres restantes, que está
racteres que se adm iten en la caja de texto. Si un día cambiase muy bien, pero no limitamos de ninguna manera que el usuario
esa longitud, no nos costaría nada reflejarlo en nuestro código pueda escribir más de 160. ¡Horror! Bueno, buen o... calma la
puesto que sólo habría que cambiar el valor de esta constante, cosa no es tan complicada de solventar. Está claro que sólo
siendo el resto de código totalmente válido. hay que modificar la úruca función que tenemos ( c a l c u l a -
También existirá en nuestro script una función que calculará r R e s t a n t e s por si no lo recuerda) para que detecte cuándo
los caracteres restantes en la caja de texto antes de llegar al lí­ liemos llegado al límite de caracteres y no nos deje escribir
mite, por tanto, para hacer ese cálculo se apoyará directamente mas. Para impedir que el usuario introduzca caracteres extra
sobre la constante declarada. El resultado de la operación se recurriremos a un truco muy tonto: sustituir el valor de la caja
escribirá en la caja de texto l o n g i t u d del formulario para que de texto con los prim eros 160 caracteres (o los que marque la
el usuario tenga constancia del espacio que le queda. constante LONGITUD_max ).

292
293
// Declaración de constante el puntero para hacer clic sobre un boton ,|,
var LONGITUD_MAX = 160; ella, pero se encontrará con una sorprivs.i: ,i h > . ■.1 , ., ,|.
function calcularRestantes(texto) { hacerlo! M uahahaahaa (risa malévola). I ,.i vi-iil.m.i. . M ,, ,, i,
// Calculamos los caracteres restantes
él y cambiará de sitio. Ahora veremos cómo ■onm p m , i.,
var resto = LONGITUD_MAX - texto.length;
m ediante JavaScript.
// Detectamos si hemos llegado al limite
if (resto < 0) { Lo prim ero es crear la página HTML que se ni. >-,li ,ti .t m I.,
// Sustituimos el texto actual nueva ventana (premio.html) y que tendrá el bolón .1 |<nl ,11
d o c u m e n t . formSMS.sms.valué = texto.
<HTML>
substr(0, LONGITUD_MAX);
<BODY>
// Forzamos la llegada al limite
<H3>¿Quieres ganar un coche?</H3>
resto = 0 ;
<F0RM ID="formulariol" NAME="formPremio">
// Escribimos el resultado en el formulario <INPUT TYPE="button" ID="botonl" NAME="botonS i." VAI.UK ":. i"
document.formSMS.longitud.valué = resto; <INPUT TYPE="button" ID="boton2" NAME="botonNo" VAI.UK "Ni."
</FORM>
) </BODY>
Si quisiéramos evitar hacer referencia a la caja de texto del </HTML>
mensaje dentro de la función, tan sólo tendremos que pasar
como parámetro la referencia directa al objeto (this, a secas) en De acuerdo, es un mensaje de lo más traicionero... pero lo
lugar de su valor. Los cam bios en la función serian mínimos. que queremos es divertir al usuario.
Para im pedir que se pueda hacer clic sobre el botón Sí
<TEXTAREA ID="entradal" NAME="sms" RC™ S = " 3'" crearemos una pequeña función que desplace la ventana en­
COLS="60" 0NKEYUP="calcularRestantes(this) ></TEXTAREA>
tera, haciendo uso del m étodo moveTo del objeto window.
// Declaración de constante
Para determinar a qué nueva posición debe dirigirse vamos
var LONGITUD_MAX = 160;
function calcularRestantes(cajaTexto) { a utilizar los milisegundos de la hora actual de m odo que las
// Calculamos los caracteres restantes coordenadas salgan un poco aleatorias ya que podemos obtener
var resto = L0KGITGD_MAX - cajaTexto.valué.length, un valor entre 0 y 999. Dado que las resoluciones de pantalla
// Detectamos si hemos llegado al limite suelen tener más píxeles a lo ancho que a lo alto, podríamos
if (resto < 0) { correr el riesgo de desplazar nuestra ventana demasiado en
// Sustituimos el texto actual
vertical (una resolución muy típica hoy por hoy es 1280x800
cajaTexto.valué = cajaTexto.valué.
substr (0, LONGITUD_MAX) ;
pixels), así que para evitarlo de un m odo sencillo dividiremos
// Forzamos la llegada al limite los milisegundos entre 2, obteniendo un valor entre 0 y 500
resto = 0; (redondeando). Esta función también iría dentro de la página
p r e m i o . h tml ", preferiblemente dentro de <HEAD>.
// Escribimos el resultado en el formulario
•:h e a d >
document.formSMS.longitud.valué = resto;
•SCRIPT TYPE="text/javascript">
Iunction esquivarüsuario () {
// Obtenemos la hora actual
var ahora = new Date();
12.5. La ventana que escapa // Calculamos las nuevas coordenadas
var x = ahora.getMilliseconds();
var y = x/2;
El efecto que se consigue con este ejercicio me resulta
// Desplazamos la ventana
particularmente gracioso ya que puede ser origen de alguna window.moveTo(x, y);
pequeña brom a en nuestra página, dándole asi un toque de I
hum or. La finalidad del código será crear una nueva ven­ •/ÍÍCRIPT>
tana (a modo de pop-up) sobre la que el usuario debe situar •/HEAD>

294 295
En cuanto al botón No, tam bién crearemos una sencilla open ("premio.html", "concui
función, tam bién dentro de <HEAD>, que muestre un mensaje "width=250,height=80, status; ii" i ,

y seguidamente cierre la ventana: c/SCRIPT>


</HEAD>
function mostrarMensaje() {
// Mostramos un mensaje
alert("¡Nos sorprende su respuesta!"); En este ejemplo no necesitamos ¡ilm .i.. i,., i , |i,|H illlli
// Cerramos la ventana de la ventana devuelto por el m étod o,.| i.. , |)(Mll
window.cióse () ; se realizam ed ian teelb o tó n N o in clu id ,,,,, i , .............
} i or ultimo, para poder comenzar la b rom .i,.. .... i,........ ..
cion al atributo H REF del enlace:
Para terminar con esta página, queda asociar estas funciones
a los manejadores ONMOUSEOVER del botón trampa, y al m a­ Haga clic c a HREF=" javascript:abrirPr.mlu()" *
nejador ONCLICK del otro botón del formulario. para descubrir el gran premio que le enp»i.i,

CINPÜT TYPE="button" ID="botonl" ="botonSi” ¿Listos para ver la reacción de los usuarios ¡’
VALUE=”Sí" ONMOUSEOVER="esquivarUsuario()">
CINPÜT TYPE="button" ID="boton2" NAME="botonNo"
VALÜE="No" ONCLICK=" mostrarMensaje()">

Con esto tendremos preparada la página lista para ser tra­


viesa con el usuario. Vam os entonces con la página que abrirá
este pop-np ( c o n c u r s o . html).
En este caso, se mostrará en la pantalla un atractivo enlace
que nos invitará a participar en un concurso. Cuando hagamos
clic sobre él, se abrirá una nueva ventana que nos revelará el
premio al que optamos.
De este modo, prim eram ente tenemos el enlace:
CHTML>
CBODY>
CH3>Concurso del díac/H3>
Haga clic CA HREF="">aquic/A> para descubrir el gran
premio que le espera.
</BODY>
C/HTML>

No hemos puesto una página destino en el enlace ya que


queremos abrirla mediante JavaScript para poder fijar algunos
atributos como el tamaño o la posición inicial. Ahora vamos
con la función que abrirá una ventana y cargará la página
" p r e m i o . ht ml " en ella. Esta nueva ventana tendrá unas di­ 12.6. Acceso restringido mediante
mensiones concretas y ocultaremos la barra de estado (pará­ una contraseña
metro opcional s t a t u s ) .
CHEAD> ¿Alguna vez ha deseado que sólo un grupo de personas
CSCRIPT TYPE="text/javascript"> pueda ver ciertas páginas de su W eb? Este ejercicio podrá
function abrirPremio() {
// Abrimos una ventana con la página del premio lodo^falible31* 6 ^ necesidad' aunque no se trate de un mé-

296
297
texto = prompt ("Por favor, int»..■In. . i, t f Q U l M f h " 1
Lo que queremos conseguir es que las personas que entrena // Si ha pulsado Cancelar o no li.t • nillw
nuestra Web tengan que introducir una contrasena (previamente if (texto == nuil || texto |
proporcionada) para poder acceder a secciones concre . // No hacemos nada
Vam os a imaginar que tenemos un enlace por cada sección return;
oue ™ o n S t , o sitio Web y que la mayoría de e los nos }
dirigen directamente a la página correspondiente, salvojuno // Comparamos si la contraseña »»■i ,|i.|
if (texto == "ChachiQueSi") (
Solicita primero una contraseña para comprobar si tenemos
// Redirigimos a la zona priv.nl.i
” noP™ a seccidn. Un conjunto posible de enlaces po- location.href = "zonaprivada .Iilmi " i
dría ser el siguiente: } else (
// En otro caso, mostramos un mnn» i|«
<H3>Lista de secciones de mi Web</^ > alert ("Lo siento, la contran(*n« tm .... i i . i . "i
_ <A HREF="fotos.html">Mis fotos</AXBR /> }
- <A H R E F = " c a n c i o n e s ,html">Mis c a n c i o n e s preferidas }
-/<A<HREF="cosas,html">Cosas que me gustan</A><BR /> Ahora que ya tenemos todo el sistema de iil.ul iimn
- <A H R E F = " J a v a S c r ipt:voi d (0) ">Zona p n v a d a < / A > tado, sólo queda com pletar el enlace de l.i .......i |niv,id.i
(con contraseña) asociando esta función a su manejador ON(' 1.1' i (Lmihicii
funcionaría si lo ponem os en el atributo HKI-ll'). |
ILista de secciones (le ini Web - <A HREF=,fjavascript:void (0) " ONCLICK
comprobarAcceso () ">Zona privada</A> (l'uii itiiil 1 . 1 i-h.i)
- Mis fotos
_ Mí<; ranclones preferidas
[A plicación JavaScript]
- Cosas que me gustan
- Zona privada (con contraseña) Por favor, introduce la contraseña

Figura 12.10. Lista de secciones.


Aceptar | Cancelar

Com o podrá deducir, los tres prim eros enlaces nos llevan
directos a la sección que representan, mientras que el ultim Figura 12.11. Petición de contraseña para entrar en la zona privada.
corresponde a una zona privada donde mostramos información
a je r io queremos que vea todo el mundo. Hemos rellenado de Opcionalmente, podemos darle un toque más profesional
momento su atributo HREF con una llamada a la función v o id a esta restricción de acceso si le damos al usuario un número
T m e v ^ a r revelar la página de destino y así solicitar la contra­ máximo de intentos para escribir la contraseña correcta, y así
t a al Dulsar ese enlace antes de redirigirnos a la sección. evitar que pruebe todas las que quiera y acabe dando con la
P a r a co m p ro b é si el visitante actual conoce la contrasena, buena. Vamos a añadir esta nueva condición a la función com­
au e le otorra el paso libre a la zona privada, vamos a construir p r o b a r A c c e s o , dando hasta tres intentos para m eter la con­
una función JavaScript (no se lo esperaba, ¿ v ^ d a jO q u e re c o g _ traseña. Para ello debemos tener una variable de ámbito global
p 1 texto introducido p oí el usuario y lo com para con la co ^ iiue nos sirva como contador de los intentos que se llevan.
traseña d T acceso v á id a . S i coincide, entonces; se le red rn g ra
• .SCRIPT TYPE="text/javascript">
hacia la página que alberga nuestro g « n secreto. En otro caso, I I Declaración de variable global
le mostraremos un m ensaje advirtiendole del erro . var numerolntentos = 0;
function comprobarAcceso() {
function com p r o b arAcceso() { // Declaración de variables
// Declaración de variables var texto;
var texto; / / S i hemos llegado al máximo de intentos
// Pedimos la contraseña al usuario

299
298
if (numerolntentos — 3) { c u p e r a r C o o k i e que creamos en el capitulo H . I .. 11, i.l.t.il.i-,
/ / N o hacemos nada cookies, para facilitarnos la tarea de manfj.u l.c. \ n ih n
return; tareas adicionales en la función compri>h.i i /\* . i. •

// Pedimos la contraseña al usuario 1. Comprobar que no tiene creada n u r s li.i, «, m i. , .le


texto = prompt("Por favor, introduce solicitarle la contraseña.
la contraseña” ); 2. Crear nuestra cookie al agotar todos lo*, m lniln |.,u,i
// Si ha pulsado Cancelar o no ha escrito nada
entrar.
if (texto == nuil I I texto == (
/ / N o hacemos nada Veamos cómo integrar la comprobación ili- I.i i<
return;
<SCRIPT TYPE="text/javascript">
// Comparamos si la contraseña es válida // Declaración de variable global
if (texto == "ChachiQueSi") { var numerolntentos = 0;
// Redirigimos a la zona privada function comprobarAcceso() (
location.href = "zona_privada.html"; // Declaración de variables
var texto;
} "¡/'incrementamos el número de intentos que lleva // Si está creada la cookie
numeroIntentos++; if (recuperarCookie("intentosAgotado»") I- "") (
// Mostramos un mensaje / / N o hacemos nada ^
alert("Lo siento, la contrasena no return;
es correcta.\n" + )
"Te quedan " + (3 - numerolntentos) I I Pedimos la contraseña al usuario
" intentos."); texto = prompt("Por favor, introduo-
la contraseña");
>
} // Si ha pulsado Cancelar o no ha escrito nnda
</SCRIPT> if (texto == nuil || texto == "") (
// No hacemos nada
return;
[Aplicación Ja va S c rip t]
}
Lo siento, la contraseña no es correcta. // Comparamos si la contraseña es válida
_L Te quedan 2 intentos,
if (texto == "ChachiQueSi") {
// Redirigimos a la zona privada
location.href = "zona_privada.html";
Figura 12.12. Mensaje con información del número de intentos } else {
restantes. // Incrementamos el número de intentos que lleva
numeroIntentos++;
// Mostramos un mensaje
Esto tiene mejor p in ta... Aunque se p o d r í a mejorar un poco alert("Lo siento, la contraseña no
más para hacer m ás efectiva nuestra restricción. es correcta.\n" +
Ahora mismo el usuario tiene tres intentos y una vez ago- "Te quedan " + (3 - numerolntentos) +
" intentos.");
tados todos ya no se le pedirá más veces la contrasena, pero
/ / S i hemos llegado al máximo de intentos
si eíu su a rio ^ s un poco picaro y recarga la página volverá a
if (numerolntentos = 3) {
tenerotros tres intentos puesto que se carga de nuevo todo el // Creamos la cookie
código y el contador se reinicia (¡ouch!). Una forma de controlar almacenarCookie("intentosAgotados", 1);
m ejor si el usuario ha agotado sus intentos P^ra en t a en la }
zona privada es crear una cookie que nos permita marcarle }
V así poder evitar concederle más oportunidades Para esto }
•/SCRIPT>
debemos recurrir a las funciones a l m a c e n a r C o o k i e y r

301
300
Cada celda se identificará mediante la concatenación de su
A hora la cookie se crea con una caducidad de sesión, es
número de fila y su número de columna, por lo que la casilla
decir hasta que cerrem os la ventana del navegador. Por lo
situada arriba a la izquierda es la "00", la de su derecha la "01"
tanto', si el usuario accede después a la pagina volvera a tener
y la siguiente la "02".
tres intentos. Esto se puede solucionar am pliando el tie™ P°
de duración de la cookie m ediante el tercer param etro de la <H3>Juego de las 3 en raya</H3>
fiinción a l m a c e n a r C o o k i e , donde podem os decir que la CTABLE BORDER="l">
<TR>
cookie se m antenga durante dos horas, cinco días, etc.
<TD ID="casillaOO” STYLE="width: 50px;
// Duración de 2 horas height: 50px"x/TD>
var caducidad = new Da t e (); <TD ID="casilla01" STYLE="width: 50px;
caducidad. setHours(hoy.getHourst) + 2); height: 50px"x/TD>
a l m a c e n a r C o o k i e ("intentosAgotados", 1, caducidad), <TD ID="casilla02" STYLE="width: 50px;
// Duración de 5 días height: 50px"x/TD>
</TR>
var caducidad = new Date O ;
caducidad. setDate(hoy.getDate() + 5 ) ; .h =h \- <TR>
a l m a c e n a r C o o k i e ("intentosAgotados", 1, caduci <TD ID="casillalO" STYLE="width: 50px;
height: 50px"X/TD>
<TD ID="casillall" STYLE="width: 50px;
height: 50px"X/TD>
12.7. Las tres en raya <TD ID="casillal2" STYLE="width: 50px;
height: 50px"X/TD>
En este último ejercicio vamos a recrear el famoso juego de las </TR>
<TR>
tres en raya o tic-tac-toe utilizando un poco de HTML y JavaScript
<TD ID="casilla20" STYLE="width: 50px;
S m o bien sabrá, la finalidad de este juego para dos personas es
height: 50px"x/TD>
situar tres figuras en línea de forma vertical, horizontal o incluso <TD ID="casilla21" STYLE="width: 50px;
diagonal dentro de un tablero cuadrado de tees casillas de anch height: 50px"x/TD>
por tees de alto (haciendo un total de nueve). O b v i a m e n t e el <TD ID="casilla22" STYlE="width: 50px;
primer jugador que lo consiga será el vencedor, aunque puede height: 50px"x/TD>
darse la posibilidad de que ninguno de ellos lo haga por estar </TR>
</TABLE>
todas las casillas rellenas sin haber logrado unía^
U na vez claras las reglas, lo prim ero de todo es dibujar cl
Juego de las 3 en raya
tablero en nuestra página, para lo que recurriremos allom as
sencillo: una tabla de tres filas por tres columnas. T am b en
aprovecharem os para identificar cada celda (que haran de
casillas del tablero) de acuerdo al siguiente esquema:

COLUMNAS
0 1 2

Figura 12.14. Nuestro tablero de juego.

Una buena forma de representar este tablero en nuestro


script sería crear un objeto con sus propiedades y métodos
específicos, de m anera que podrem os aplicar todo lo que
Figura 12.13. Esquema de nombrado de celdas.
303
dando por finalizada la partida. Si no es así, entonces
debe cambiar el tum o a la otra figura, siempre y cuando
haya posiciones libres donde ponerla.
propiedades:
. c a s i l l a s : Representarán, obviamente, todas las posi- Después de este análisis, nuestro objeto quedaría formado
así:
ciones en las ¿ se puede situar una f i g u r a ' o g r a
el obietivo del juego. La forma de recrearlo sera a través
de un array bidim ensional que verem os mas adelante. Objeto tablero
En cada posición se almacenará la figura que la ocup . casillas
. t u r n o : Indica cuál de las dos figuras P O ^ e n e ^l Propiedades turno
turno actual. Las representaremos mediante los carac numMovimientos
inicializarTablero
. ¡ ^ M o v i m i e n t o s : E s un c o n t a t o del núm ero do detectarLineaHorizontal
m ovimientos o figuras que ya se han sitüado sobre e detectarLineaVertical
Métodos
tablero Esto nos ayudará a determmar cuando ha ter detectarLineaDiagonal
minado la partida por no quedar huecos libres. Ademas, detectarLinea
X p r o b a L s t a propiedad será más rápido que recorrer marca rMovimi^nto
el tablero entero en busca del número de casillas sm
Figura 12.15. Nuestro objeto tablero.
utilizar.
En cuanto a los m étodos, también tendrem os los mismos Ahora ya podemos comenzar a trasladar todas estas pa­
que en la vida real: labras a código JavaScript. Empezaremos por lo más básico,
. i n i c i a l i z a r T a b l e r o : Deja el tablero vacío listo para crear la estructura del objeto T a b l e r o :
empezar una nueva partida y también establece a que function Tablero() {
figura corresponde el primer turno. Asimismo, establece // Lista de propiedades
que el número de movimientos realizados es cero puesto // Lista de métodos
}
aue vamos a comenzar a jugar.
. d e t e c t a r L i n e a : Este m étodo se encarga de analizar Después vendrán las propiedades que, recuerde, deben ir
la situación actual del tablero para com probar si hay junto con la sentencia t h i s .
una jugada vencedora, es decir, alguien ha conseguí
// Lista de propiedades
las tres en raya. Para ello debe exam inar las casillas en this.casillas;
horizontal, vertical y diagonal en busca de tres figura this.turno;
iguales seguidas. Con el fin de sim phficarlaapariencia this.numMovimientos;
del código crearemos tres pequeños métodos auxiliares
para cada uno de los posibles tipos d e detec Como dijimos al definir la propiedad c a s i l l a s , el tablero
tarLineaHorizontal, d e t e c t a r L m e a V e r t ic a l estará representado mediante un array bidimensional de 3x3
posiciones. Para conseguir esto debemos crear primero un array
. L ^ a r M o v i m i e n t o : ' t o r d a una ju gada sobre el unidimensional de tres posiciones para después convertir cada
tablero fijando en la casilla indicada la figura del turno una de ellas en otro array unidimensional de tres posiciones,
£ ' e I n c r e m e n t a n d o el núm ero de m ovim ientos con lo que obtenemos un total de nueve posiciones.
realizados en la partida. Aquí tam bién definiremos un Iliis .casillas = new ñrray(3);
método auxiliar ( c o n t i n u a r P a r t i d a ) que: se e^ a r§ a ra tur(var i=0; i<3; i++) {
de comprobar si este movimiento causa la victoria dei this.casillas[i] = new Array(3);
r u g a d X c tu a l mediante el m étodo d e t e c t a r L i n e a , I

305
Hecho. No es necesario inicializar las otras propiedades
Por ultimo, el método también iguala .i ......... ,,
ya que lo harem os desde su método i n i c i a l i z a r T a b l e r o , de movimientos en la jugada actual. Esto cn l,„ i !
el cual debe vaciar el tablero primeramente, acción que com­
/ / R e m i d a m o s el número de movimientos
prenderá dos fases: this.numMovimientos = 0;
1. Dejar el array c a s i l l a s sin figuras en todas las posi­
Veamos entonces la construcción completa di'l .......... ,
ciones, sustituyéndolas por una cadena vacía que tenga una visión global del mismo.
2. L im piar la tabla H TM L que rep resen ta el tablero
para que los jugadores puedan volver a colocar sus this.inicializarTablero = function (){
// Declaramos las variables
figuras. var azar = Math.round(Math.random());
Com o am bas fases están directam ente relacionadas, las // Limpiamos las casillas
for(var fila=0; fila<3; fila++) {
realizaremos en un único paso. Lo harem os definiendo dos
for(var col=0; col<3; col++) {
bucles f or: uno para recorrer las filas y otro para las columnas,
this.casillas[fila][col] = "";
de manera que pasaremos por todas las posiciones posibles.
document.getElementByld("casilla" + fila +
Además, como hem os creado el identificador de cada casilla col).innerHTML = "finbsp;";
de la tabla HTML como la com binación del número de fila y
de columna, nos será realmente fácil acceder a ellos mediante } '''
estos bucles y el método g e t E l e m e n t B y l d . Para borrar la // Establecemos el turno
if (azar == 0) {
figura de la celda usarem os su propiedad innerHTML y el this.turno = "O";
espacio en blanco de HTML (&nbsp). } else {
this.turno = "X";
// Limpiamos las casillas )
for(var fila=0; fila<3; fila++) {
for(var col=0; col<3; col++) { // R e m i d a m o s el número de movimientos
this.casillas[fila][col] = this.numMovimientos = O -
document.getElementByld("casilla" + fila + col) .
}
innerHTML = "&nbsp;";
Los siguientes métodos que implementaremos serán los
} relacionados con la comprobación de una jugada ganadora
}
Empezaremos por la más sencilla: detectarLineaDiagonal"
Adicionalmente, dentro de este método tenem os que esta­ ara saber si existe una jugada en diagonal que finalice la partida
blecer a qué figura corresponde el prim er turno. Para hacerlo
de una forma original recurriremos al azar gracias al método m eeHa°bSlero- C° mpr° bar las dos ú lá cas A g o n a le s que existen
random del objeto Math, de modo que, una vez redondeado
el número aleatorio (método round), establecerem os el turno 1. La que va desde la casilla superior izquierda (fila 0 y
para la figura "O" si sale un cero, o por el contrario a la figura columna 0) hasta la inferior derecha (fila 2 y columna
"X" si sale un uno. Sólo podremos obtener esos dos valores
puesto que random da un número real comprendido entre 2. La que va desde la casilla superior derecha (fila 0 v
ellos que además rendondearemos. columna 2) hasta la inferior izquierda (fila 2 y columna

II Establecemos el turno
Como es indiferente el sentido dentro de la diagonal (arriba

lievai&onL’°a“aa,TÍba)"°habrá**1"“r
var azar = Math.round(Math.random()) ;
if (azar == 0) (
this.turno = "O";
} else ( quet una l’ugada sea válida en diagonal, sus casillas
this.turno = "X"; t deben estar vacias y además contener la misma figura en
} elIas- En realidad nos basta con com probar si la primera

306
307
casilla no está vacía para después comprobar que todas tienen this.casillas[1 ] [col] - this.casi]I„n|j ,[tml., ,
la misma figura, ya que si contienen una figura no estaremos return true;
comparando con el valor vacío. }
I
this.detectarLineaDiagonal = function () { I I En otro caso, no hemos encontrado una Urina
// Comprobamos la diagonal hacia la derecha return false;
if (this.casillas[0][0] != "" && }
this.casillas[0][0] == this.casillas[1][1] &&
this.casillas[1][1] == this.casillas[2][2]) { Con todos estos métodos auxiliares definidos, el niélenlo
return true; d e t e c t a r L in e a nos queda la mar de sencillo de implenn-ntai
} puesto que bastara con comprobar cada uno de los tres p<.sibl.-s
I I Comprobamos la diagonal hacia la izquierda tipos de lmeas (horizontales, verticales y diagonales).
if (this.casillas[0][2] != "" &&
this.casillas[0][2] = this.casillas[1][1] && this.detectarLinea = function () {
this.casillas[1][1] == this.casillas[2][0]) ( return this.detectarLineaHorizontal() ||
return true; this.detectarLineaVertical() ||
this.detectarLineaDiagonal() ;
}
I I En otro caso, no hemos encontrado una linea
return false;
Escrito de esta forma, en cuanto haya una jugada válida
) en alguna de las tres situaciones, el método detectarLinea
Ahora nos iremos en las que realizan esta comprobación, revelara que existe.
pero de forma horizontal o vertical, cuyo funcionamiento es
pI tal P° r ah° ra? Esper° que bien‘ Vamos entonces con
muy similar. El método detectarLineaHorizontal debe el método co n t m u arPartida que comprueba si el último
recorrer cada fila para comprobar si la figura de todas las co­ m ovim iento otorga la victoria al ju gad or actual (m étodo
lumnas es la misma, mientras que detectarLineaVertical detectarLinea), mostrando un mensaje de enhorabuena
recorrerá cada columna comprobando las figuras en cada fila. al ganador y dando por finalizada la partida. En otro caso
En ambas también nos aseguraremos de que la primera casilla cambiara el turno si quedan posiciones libres en el tablero (o
no está vacía, tal y como hicimos al escribir detectarLinea­ lo que es lo mismo, no hemos hecho el máximo número de
Diagonal. Estos métodos quedarían entonces así: movmuentos) o muestra un mensaje indicando que la partida
ha terminado si no es así.
this.detectarLineaHorizontal = function () {
I I Comprobamos cada fila this.continuarPartida = function () {
for(var fila=0; fila<3; fila++) ( I I Si hay tres en raya
if (this.casillas[fila][0] != "" && if (this.detectarLinea()) {
this.casillas[fila][0] == this.casillas[fila] // Finalizamos la partida
[1] SS this.numMovimientos = 9;
this.casillas[fila][1] == this.casillas[fila] // Damos la enhorabuena
[2]) ( alert("¡Tres en raya! Enhorabuena ") •
return true; ) else (
} I I I Si no ha terminado la partida
) if (this.numMovimientos < 9) {
/ / E n otro caso, no hemos encontrado una linea // Cambiamos el turno
return false; if (this.turno == "O") {
} this.turno = "X";
this.detectarLineaVertical = function () ( ) else {
// Comprobamos cada columna this.turno = "O";
for(var col=0; col<3; col++) ( }
if (this.casillas[0][col] != "" && } else {
this.casillas[0][col] = this.casillas[l][col] && // En otro caso, avisamos del final de la partida

308
309
alertC'La partida ha terminado sin vencedor."); // In icia liz a m o s el ta b le ro

) tresE n P aya.i n i c i a l i zarT ab lero ();

) )
</SCRIPT>
)
</HEAD>
Escribamos finalmente el último método que nos queda <BODY ONLOAD=" c i e a r T a b 1e r o ( ) " >
por incluir: marcarMovimiento. Aquí debem os registrar
la jugada realizada sobre el tablero, guardando la figura del Seguidamente, y ya para terminar, hay ( , | u . i,n .iliu m .
tum o actual en la casilla que reciba como parámetro (si no c l i c k de cada una de las celdas (etiquetas TI> ) nli,* |Ui>
está ocupada y no ha terminado la partida, claro) y también ción que registre el movimiento realizado, ya ipu - 1 .1.....I. .i
sumando el movimiento al contador general (propiedad num- usuario va a pulsar para situar las figuras. Sin rin l'.ii}............
Movimientos). Inm ediatamente después hay que mirar si vez no serán manejadores a través de HTML, sinml. |.>........... i (,i
la partida sigue o no, que lo dejaremos en manos del método puesto que vamos a asociar la misma función a Un l« •. <II.. , ......
continuarPartida. futura modificación, por ligera que sea, nos obll>,,.. i.i .........
biar los nueve manejadores. Haciéndolo a través il. |. r .
this.marcarMovimiento = function (fila, col) { podemos asignar de 'un plum azo' la misma f u n c i m i ,i i . <<I , .
// Si no ha terminado la partida
evitando que una modificación en su código no ulr. Ir .........
if (this .numMovimientos < 9) (
funciones sino a una sola.
// Si la casilla no está ocupada
if (this.casillas[fila][col] == "") ( De este modo, veamos qué debe hacer la funi mu .|ii. ...
// La ocupamos gistra el movimiento:
this.casillas[fila][col] = this. turno;
document.getElementByld("casilla" + fila + • Obtener la fila y la columna a la que co n v .p .m .lr I..
col).innerHTML = this.turno; celda actual a través de su identificador, d.nln i|ii. . i.,
I I Incrementamos el número de movimientos información corresponde a sus dos últimos u im . leu
this.numMovimientos++; • Llam ar al m étodo m a r c a r M o v im ie n t o ilel oh|rU»
// Comprobar si sigue la partida
T a b l e r o para que el movimiento quede re^isli.uln
this.continuarPartida() ;
pasando como parámetros la fila y columna ol>lcm. I...
} en el paso anterior.
}
1 Antes de ver estos pasos transformados en código vamos .i
Bueno, pues nuestro objeto Tablero ya está por fin com­ explicar cómo será su asignación a los manejadores. Después
pleto. Tan sólo nos quedaría preparar la tabla HTML (que veremos ambas operaciones juntas.
hace de tablero) para que el usuario pueda interactuar con él Como todos los elementos HTML a los que tenemos que
y echarse una partidita con alguien. incluir un manejador son celdas de una tabla, podemos aprove­
Primeramente hay que crear un nuevo tablero en una va­ chamos del método getElementsByTagName que nos ofrece
riable global (tresEnRaya) e implementar una función que el objeto document gracias al cual podremos agrupar en un
se encargará de inicializarlo. Esta función la asociaremos al ai my todas las celdas para después asignarles el manejador una
evento ONLOAD del documento para que realice las operaciones a una dentro de un bucle for. La única restricción que supone
al cargar la página. hacer esto es que en la página no puede haber más celdas que no
correspondan al tablero, puesto que les asignaríamos el mismo
<HEAD> manejador erróneamente. Si eso fuese inevitable podríamos
<SCRIPT TYPE="text/javascript">
solucionarlo haciendo un pequeño filtro a la hora de asignar el
I I Declaramos una variable global
var tresEnRaya;
manejador, comprobando si el identificador de la celda comienza
function crearTablero() ( por "casilla" por ejemplo (es una idea de tantas).
H Creamos una instancia del tablero Vamos, ahora sí, a escribir el código que dotará de vida al
tresEnRaya = new Tablero(); tablero de nuestra página:

310 311
// Obtenemos todas las celdas de la tabla
var celdas = document.getElementsByTagName("TD");
// Asignamos el manejador a todas las celdas
for(var i=0; icceldas.length; i++) {
// Asignamos el manejador
celdas[i].onclick = function ()(
// Obtenemos la fila (penúltimo carácter)
var fila = this.id.substr(-2, 1);
// Obtenemos la columna (último carácter)
var columna = this.id.substr(-1);
// Registramos la jugada en el tablero ITres en raya! Enhorabuena.

tresEnRaya.marcarMovimiento(fila, columna);
)
>
Sólo destacar que este último código debe situarse al final Figura 12.18. Final de partida con vencedor.
de la página ya que necesita que exista la tabla para poder
asignarle un manejador. Si lo pusiéramos al principio no encon­ Me gustaría además aprovechar este ejemplo para mostrarle
traría ningún elemento de celda puesto que se definirían justo a cómo puede reutilizar fácilmente el objeto tablero en otras
continuación. Otra opción sería incluirlo como parte del código páginas, sin tener que copiar el código en ella. Si recuerda
que se ejecuta con el manejador O N L O A D del documento. del capítulo de introducción se comentó que se podía realizar
Pues dicho esto, ya estaría todo listo para jugar. ¿Qué, una esto utilizando el atributo SRC de la etiqueta <SCRIPT> junto
partidita:)? con un fichero de extensión ”.js". Para este ejemplo, el fichero
podría llamarse objeto_tablero.js" que incluiría el siguiente
código (así de paso puede ver todo agrupado, en lugar de
desperdigado):
I I Declaración del objeto tablero
function Tablero() {
// Lista de propiedades
this.casillas = new Array(3);
for(var i=0; i<3; i++) {
this.casillas[i] = new Arr ay(3);
Figura 12.16. Transcurso de una partida. )
t h i s .turno;
this.numMovimientos;
0 X 0
// Lista de métodos
X X 0 this.inicializarTablero — function (){
// Declaramos las variables
var azar = Math.round(Math. r a n d o m ());
X o X I I Limpiamos las casillas
1 [A p lic a c ió n J a v a S c r ip t] for(var fila=0; fila<3; fila++) {
m
for(var col=0; col<3; col++) {
La partida ha terminado sin vencedor.
this.casillas[fila][col] =
&
document.getElementByld("casilla" + fila +
| Aceptar | col).innerHTML = "Snbsp;";
)
)
Figura 12.17. Final de partida sin vencedor. // Establecemos el turno

312 313
if (azar == 0) {
this.turno = "0"; this.detectarLinea = function () {
} else ( return this.detectarLineaHorizontal() ||
this.turno = "X"; this.detectarLineaVertical() ||
) this.detectarLineaDiagonal();
// Reiniciaraos el número de movimientos >
this.numMovimientos = 0; this.continuarPartida = function () (
} / / S i hay tres en raya
this.detectarLineaDiagonal = function () { if (this.detectarLinea()) (
// Comprobamos la diagonal hacia la derecha // Finalizamos la partida
if (this.casillas[0][0] != "" && this.numMovimientos = 9;
this.casillas[0] [0] == this .casillas[1][1]&& // Damos la enhorabuena
this.casillas[1][1] = this.casillas[2] [2]) { alert("¡Tres en raya! Enhorabuena.");
return true; } else (
} I I I Si no ha terminado la partida
// Comprobamos la diagonal hacia la izquierda if (this.numMovimientos < 9) (
if (this.casillas[0][2] != "" && // Cambiamos el turno
this.casillas[0][2] == this.casillas[1][1]&& if (this.turno == "O") (
this.casillas[1][1] == this.casillas[2][0]) { this.turno = "X";
return true; ) else (
) this.turno = "O";
/ / E n otro caso, no hemos encontrado una linea }
return false; t else (
í / / E n otro caso, avisamos del final
this.detectarLineaHorizontal = function () { // de la partida
// Comprobamos cada fila alert("La partida ha terminado sin
for(var fila=0; fila<3; fila++) { vencedor.");
if (this.casillas[fila][0] != "" && )
this.casillas[fila][0] == this. )
casillas[fila][1] S& )
this.casillas[fila][1] == this. this.marcarMovimiento = function (fila, col) (
casillas[fila][2]) { // Si no ha terminado la partida
return true; if (this.numMovimientos < 9) {
) // Si la casilla no está ocupada
} if (this.casillas[fila][col] = "") {
/ / E n otro caso, no hemos encontrado una linea // La ocupamos
return false; this.casillas[fila][col] = this.turno;
) document.getElementByld("casilla" + fila +
this.detectarLineaVertical = function () ( col).innerHTML = this.turno;
// Comprobamos cada columna // Incrementamos el número de movimientos
fo r (var col=0; col<3; col++) ( this.numMovimientos++;
if (this.casillas[0][col] != "" && // Comprobar si sigue la partida
this.casillas[0] [col] == this.casillas[1] this.continuarPartida();
[col] & & )
this.casillas[1][col] == this.casillas[2] }
[col]) I f
return true; I

} Gracias a esto, el código de la página quedará más despejado


// En otro caso, no hemos encontrado una línea puesto que sustituiríamos todo lo anterior por esta única línea,
return false; dentro de < H E A D > , quedando la página completa como sigue:'

314 315
<HTML> I I Obtenemos la fila (penúltimo carácter)
<HEAD> var fila = this.id.substr(-2 , 1);
<SCRIPT TYPE="text/javascript" SRC="objeto_tablero. // Obtenemos la columna (último carácter)
js"X/SCRIPT> var columna = this.id.substr(-1 );
<SCRIPT TYPE="text/javascript"> I I Registramos la jugada en el tablero
I I Declaramos una variable global tresEnRaya.marcarMovimiento(fila, columna);
var tresEnRaya;
function crearTablero() { )
I I Creamos una instancia del tablero </SCRIPT>
tresEnRaya = new tablero(); </BODY>
I I Inicializamos el tablero </HTML>
tresEnRaya.inicializarTablero();
} No quiero resultarle pesado, ya que este ejemplo ha sido
</SCRIPT> bastante largo, pero no me gustaría despedirme sin antes darle
</HEAD> otra pequeña idea que mejoraría a nivel visual nuestro mara­
<BODY ONLOAD="crearTablero()"> villoso script: poner en negrita la jugada ganadora;).
<H3>Juego de las 3 en raya</H3>
Si lo piensa detenidamente y analizando el código que te­
<TABLE B0RDER="1">
nemos, seguro que encuentra un sitio donde se puede incluir
<TR>
<TD ID="casillaOO" STYLE="width: 50px; este cambio sin mucho esfuerzo: las funciones que detectan si
height: 50px"x/TD> hay una jugada ganadora. Dentro de ellas podemos aprove­
<TD ID="casilla01" STYLE="width: 50px; char para saber la combinación ganadora y ponerla en negrita
height: 50px"X/TD> ni mismo tiempo. Y pensará ¿cómo lo ponem os en negrita?
<TD ID="casilla02" STYLE=”width: 50px; Pues muy fácilmente, sustituyendo el contenido de las celdas
height: 50px''x/TD>
correspondiente con la misma figura pasando por el método
</TR> bold del objeto String.
<TR>
<TD ID="casillalO" STYLE="width: 50px; this.detectarLineaDiagonal = function () (
height: 50px"x/TD> // Comprobamos la diagonal hacia la derecha
<TD ID="casillall" STYLE="width: 50px; if (this.casillas[0 ][0 ] != "" &&
height: 50px"x/TD> this.casillas[0 ] [0 ] == this.casillas[1 ][1 ] sí
<TD ID="casillal2" STYLE="width: 50px; this.casillas[l][1 ] == this.casillas[2 ][2 ]) {
height: 50px"x/TD> // Ponemos las celdas en negrita
</TR> document.getElementByld("casillaOO").
<TR> innerHTML = this.casillas[0][0].bold();
<TD ID="casilla20" STYLE="width: 50px; document.getElementByld("casillall").
height: 50px"x/TD> innerHTML = this.casillas[1][1],bold();
<TD ID="casilla21" STYLE="width: 50px; document.getElementById("casilla22") .
height: 50px"x/TD> innerHTML = this.casillas[2][2],bold();
<TD ID="casilla22" STYLE="width: 50px; return true;
height: 50px"x/TD> )
</TR> // Comprobamos la diagonal hacia la izquierda
</TABLE> if (this.casillas [0 ] [2 ] != &&
<SCRIPT TYPE="text/javascript"> this.casillas[0 ][2 ] == this.casillas[1 ][ 1 ] &&
I I Obtenemos todas las celdas de la tabla this.casillas[l][1 ] == this.casillas[2 ][0 ]) {
var celdas = document.getElementsByTagName(”TD"); // Ponemos las celdas en negrita
I I Asignamos el manejador a todas las celdas document.getElementByld("casilla02").
for (var i=0; K c e l d a s .length; i++) { innerHTML = this.casillas[0][2].bold();
// Asignamos el manejador document.getElementByld("casillall")
celdas[i].onclick = function ()( innerHTML = this.casillas[1][1],bold();

316 317
document.getElementByld("casilla20").
innerHTML = this.casillas[2][0].bold();
return true;
}
// En otro caso, no hemos encontrado una línea
return false;
)
this.detectarLineaHorizontal = function () {
// Comprobamos cada fila
for(var fila=0; fila<3; fila++) {
if (this.casillas[fila][0] != "" SS
this.casillas[fila][0] == this.casillas[fila]
[1] &&
this.casillas[fila][1] = this.casillas[fila]
[2]) {
// Ponemos las celdas en negrita
document.getElementByld("casilla" + fila +
"0").innerHTML = this.casillas[fila][0].
bold () ;
document.getElementById("casilla" + fila +
"1").innerHTML = this.casillas[fila][1].
bold () ;
document.getElementByld("casilla" + fila +
"2").innerHTML = this.casillas[fila][2].
bold();
return true;
)
1
I I En otro caso, no hemos encontrado una línea
return false;
)
this.detectarLineaVertical = function () (
I I Comprobamos cada columna
for(var col=0; col<3; col++) {
if (this.casillas[0][col] != "" &&
this.casillas[0][col] = this.casillas[1][col] &&
this.casillas[1][col] == this.casillas[2][col]) (
I I Ponemos las celdas en negrita
document.getElementById("casillaO" + col).
innerHTML = this.casillas[0][col].bold();
document.getElementByld("casillal" + col).
innerHTML = this.casillas[1][col].bold();
document.getElementByld("casilla2" + col).
innerHTML = this.casillas[2][col].bold();
return true;
}
)
// En otro caso, no hemos encontrado una línea
return false;
)

318
13
Un paso más allá
de JavaScript

Con todo lo que ha visto en esta guía, tengo la convicción


de que está preparado para enfrentarse a m uchos retos e in­
cluso seguir avanzando en el dominio de JavaScript porque,
aunque no lo crea, esto es casi sólo la punta de iceberg. Pero
no tema puesto que ya tiene unos buenos cim ientos para
comprender rápidam ente las múltiples técnicas que se basan
en este lenguaje.
En este capítulo pretendo m ostrarle las más inmediatas
cuando se quiere subir el nivel de nuestras páginas Web.

13.1. DHTML
Seguro que le suena haberlo leído alguna vez por está guía,
junto a otro montón de palabros del mismo calibre. DHTML,
o HTML Dinámico, es una poderosa combinación de HTML,
hojas de estilo CSS y JavaScript que nos va a permitir incor­
porar variedad de efectos en nuestras páginas, así como la
posibilidad de aumentar la interacción con el usuario que la
visita. Por tanto, nuestras páginas dejarán de ser un simple y
aburrido conjunto de texto, imágenes, tablas y otros elementos
estáticos.
Además, se suele hacer un uso muy intensivo del DOM (es
amplísimo) llegando a poder manipular el contenido de una
página casi por completo.
Voy a exponer un ejemplo sin adentrarme mucho, que para
eso hay libros específicos muy buenos, con el objetivo de que
vea un poco el potencial de DHTML. No creo que le suponga
problema el com prender la gran mayoría del código.

319
</STYLE>
Partiremos con una página en la que habrá varias capas con </HEAD>
palabras en inglés que, al pulsar sobre ellas, aparecerá otro re­ <BODY>
cuadro con la traducción al español. Estas traducciones estaran <DIV ID="traduccÍonl" CLASS="traduccion oculto">Perro</DIV>
previamente cargadas en nuestra página como capas ocultas, <DIV ID="traduccion2" CLASS="traduccion oculto">Casa</DIV>
de modo que la pulsación sobre una caja en inglés hara visible <DIV ID="traduccion3" CLASS="traduccion oculto">Silla</DIV>
<DIV CLASS="caja">Dog</DIVXbr>
su correspondiente traducción.
<DIV CLASS="caja">House</DIVXbr>
<DIV CLASS="caja">Chair</DIV>
</BODY>
Dog </HTML>

Le paso a comentar brevemente cada estilo que se ha in­


cluido, por si no conoce estas definiciones.
House
• visible: Como puede imaginar, nos permite hacer visible
una capa.
• oculto: Muy obvia también, nos permite ocultar una
capa.
Chair
• caja: Es el estilo que aplicaremos a las cajas con el texto
en inglés. Se ajustarán sus dimensiones, se pondrá un
Figura 13.1. Página inicial. borde de color rojo y haremos que aparezca el cursor
en forma de mano cuando nos pongamos sobre una de
También estará presente algo que no hemos utilizado en estas cajas.
este libro: estilos CSS. Serán muy sencillos para no complicar • traducción: Muy similar al anterior, pero aplicada a las
el ejemplo. traducciones en español. Como añadido, se colorea el
fondo de la capa con un gris claro (#F0 FOFO) y se fija su
<HTML> posición como absoluta, es decir, nos permitirá cambiar
<HEAD> su posición respecto al documento.
<STYLE>
.visible { Por lo demás, nada raro excepto el uso del atributo CLASS
display: block;
que sirve para asignar estilos a un elemento de la página.
} ¡Pero vamos a la "chicha"! Tendrem os que crear dos fun­
.oculto {
display: none; ciones para m ostrar u ocultar las traducciones. Para ello
) tendremos que cam biar la propiedad className de la capa
.caja { (nueva para nosotros) con los estilos que correspondan en
border: lpx solid red; i ada caso. Además, para darle un poco de estilo, vamos a
width: 150px; hacer que la capa aparezca cerca de la posició