domingo, 19 de enero de 2014

Ventanas, marcos y arreglos en JavaScript

Al hablar del objeto window, lo primero que se puede venir a la mente de muchos son las alusiones a los sistemas operativos elaborados por la empresa Microsoft. Sin embargo, el concepto del que hablaremos aquí no tiene ninguna conexión directa con alguna empresa comercial ya que el concepto es completamente independiente de la plataforma utilizada, salvo el hecho de que la palabra ha sido prácticamente expropiada por una empresa en particular para mantener un vasto predominio en el mercado de los sistemas operativos.

Al poner en marcha un navegador Web, después de un breve tiempo aparece en la pantalla la página Web de inicio. El espacio de la pantalla en donde aparece esa página es una “ventana” grande que tiene arriba algunos controles de navegación y quizá cierta información de estado abajo en la barra horizontal inferior de la página. Todo lo que aparece dentro de una página Web debe aparecer dentro de esa “ventana”, y por esta razón la ventana es considerada como el objeto de nivel más alto de un documento HTML.

Desde el punto de vista de la programación orientada-a-objetos y la convención DOM (Document Object Model), todo lo referente a la página Web (su color de fondo, las cajas de texto, las imágenes, etcétera) es una propiedad de la ventana. La ventana, en términos de JavaScript, es considerada como un objeto, el objeto window.

Si examinamos la base de la ventana (la barra horizontal inferior al pie de la página), veremos que después de que se ha terminado de cargar el navegador aparece en el área pequeña del marco inferior un mensaje que dice algo como “Document: Done”. Esta área es la línea de estado, y el navegador la usa para presentar mensajes de estado a la persona que usa el navegador, como el mensaje de estado que nos dice que el documento terminó de cargarse o que nos confirma los hipervínculos que están siendo accesados mientras un documento enviado por Internet se va cargando en la máquina. Con la propiedad status del objeto window podemos crear nuestros propios mensajes para que sean exhibidos en la línea de estado. La sintaxis para establecer un mensaje de estado en la línea de estado es la siguiente:

window.status = "texto del mensaje"

A modo de ejemplo, con el siguiente código se crea una página Web con dos botones, rotulados “Oprime este botón” y “Ahora oprime este botón”, para lo cual definimos la función mensaje(texto) que sirve como manejador de eventos; cuando el usuario hace clic en cualquiera de los botones la línea de estado exhibe un mensaje apropiado.



<HTML>

    <HEAD>

    <TITLE>Ejemplo de mensajes en línea de estado</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
     
       function mensaje(texto) {
          window.status = texto
          }
       
    </SCRIPT>

    </HEAD>

    <BODY>

      <FORM>
         <input type="button" value="Oprimir este botón" onClick="mensaje('Muy bien')">
      </FORM>
   
      <FORM>
         <input type="button" value="Ahora oprime este botón" onClick="mensaje('¡Bravo!')"
      </FORM>
   
   </BODY>

</HTML>



Si se carga el archivo anterior en un navegador (guardado como un documento “.htm” o “.html”) aparecerá una ventana con dos botones. Haciendo clic en forma alternada en dichos botones aparecerá el mensaje “Muy bien” o el mensaje “¡Bravo!”. Con la ayuda de un bucle perpetuo en JavaScript podemos usar esta misma propiedad de status para poner un texto móvil en la línea de estado que se va desplazando de derecha a izquierda a manera de anuncio llamativo (posiblemente el lector ya habrá visto algunos de estos anuncios en el borde inferior al visitar algunos sitios en Internet).

Con HTML y JavaScript no sólo podemos hacer que aparezcan cosas en una ventana ya sea en forma estática o en forma dinámica. Podemos también crear ventanas nuevas en donde se pueden poner cosas que por alguna razón queremos mantener separadas de las cosas que hay en la ventana principal (al final de esta entrada veremos un ejemplo de una mini-base de datos en la cual se hace uso de este recurso). Para ello, tenemos los métodos open() y close(), usados para hacer nacer y morir ventanas. Con el método open(), el cual es una propiedad del objeto window, se crea una ventana totalmente nueva del navegador. La ventana actual seguirá allí, pero se pone una ventana nueva en el escritorio que es básicamente otro navegador Web, y el programador puede definir las características de esta ventana nueva (tamaño, título, botones de navegación disponibles, etcétera). Podemos usar este método para mostrar en una página Web un ejemplo de algo en otra página sin que se tenga que cerrar la ventana principal. La sintaxis del método open() es:

window.open("URL por abrir", "nombre", "característica(s)")

URL es la dirección del documento que se desea abrir en una ventana nueva, por ejemplo:

http://MiDoc.html 

mientras que el “nombre” es un nombre interno para darle un nombre a la página nueva y que se puede usar en las referencias de la programación JavaScript pero que no aparece en un lugar visible de la ventana. A continuación tenemos una muestra de código que permite abrir dos ventanas nuevas desde la ventana principal (para que se puedan abrir las dos ventanas secundarias, es importante no tener activada en el navegador la opción de bloqueo de ventanas emergentes que usualmente se activa y desactiva en alguna selección del menú del navegador como “Block pop-up windows” que a su vez puede estar bajo algún rubro como “Herramientas”, o sea “Tools”):



<HTML>

   <HEAD>
      <TITLE>Creación de ventanas múltiples bajo JavaScript</TITLE>
 
   <SCRIPT LANGUAGE="JavaScript">
 
      window.open("", "PrimeraVentana", width=400, height=300);
      window.open("", "SegundaVentana", width=400, height=300);

   </SCRIPT>
 
   </HEAD>

   <BODY bgcolor="#FFFF00">

   <h2>Esta es la ventana progenitora</h2>

   </BODY>

</HTML>



Por su parte, el método close() se usa para cerrar una ventana, y debe estar contenido en código JavaScript dentro de la ventana que se desea cerrar.

Al haber dos o más ventanas en el escritorio, necesitamos alguna manera de poder dirigirnos a cada una de ellas y poder manipularlas no solo desde el código de la ventana principal (la primera ventana en abrirse) sino también desde la ventana actual. La propiedad opener nos permite modificar la primera ventana (la ventana que abrió la ventana actual) usando código desde la ventana actual. En una porción de código JavaScript que se haya cargado en la ventana actual, la instrucción:

window.opener.close()

hace que se cierre la primera ventana (a la primera ventana se le llama en inglés la ventana “opener” por ser la primera que abre la secuencia de la aparición de ventanas posteriores). Del mismo modo, podemos hacer cambiar el color de fondo de la primera ventana a amarillo con una instrucción como la siguiente:

window.opener.document.bgColor="Yellow"

Un objeto que esporádicamente puede ser utilizado cuando hay ambigüedad es el objeto self, el cual es un sinónimo del objeto window. De este modo:

self.status="Léase con cuidado"

es lo mismo que:

window.status="Léase con cuidado"

La intención original para haber definido el objeto sinónimo self fue evitar un conflicto posible ocasionado por la notación. Supóngase que se crea un formulario en la página Web con la etiqueta <FORM> que tenga el nombre interno “status” definido mediante el atributo NAME= de la etiqueta <FORM>. Si esto llega a ocurrir en una construcción de propiedad de window, no será claro si el programador se está refiriendo a la propiedad status de línea de estado de la ventana o al elemento de formulario llamado “status”, dándose por lo tanto al programador la opción de usar:

self.propiedad

en los casos en los que pueda haber ambigüedad. Aunque lo más elegante es eliminar de raíz las ambigüedades asignando nombres adecuados de modo tal que no haya conflictos.

Dentro de una ventana se puede hacer que aparezcan cajas de diálogo, las cuales son consideradas en algunos tratados como ventanas de mensaje (estrictamente hablando, no son ventanas, sólo son cajas de diálogo), usadas para llamar la atención del usuario sobre algo que se considera importante, todas las cuales son invocadas como métodos del objeto window. Estas son:
Ventana de alerta.- Usada para proporcionar información de alerta, se invoca con una línea de código como la siguiente:

   window.alert("mensaje")

Ventana de confirmación.- Invocada con una línea de código como la siguiente:

   window.confirm("mensaje")

el método confirm() devuelve el valor true (verdadero) si el usuario selecciona la opción “OK”, o false (falso) si el usuario escoge “Cancel”.

Ventana de solicitud.- Invocada con una línea de código como la siguiente:

   variable = window.prompt("mensaje de solicitud", valor predeterminado)

el método prompt() tiene en un “mensaje de solicitud” lo que se está pidiendo al usuario que proporcione, mientras que el valor predeterminado (opcional) representa un dato que tal vez se quiera que aparezca en la solicitud de manera predeterminada.
Casi todos estamos familiarizados con el concepto de “poner el foco” en una ventana o “quitarle el foco”, al haber varias ventanas abiertas con el solo hecho de hacer clic con el mouse en una de ellas basta para poner en foco dicha ventan y quitarle el foco a las demás ventanas. Sobre esto, hay dos métodos de window que son focus() y blur(), los cuales nos permiten (respectivamente) “poner en foco” o “quitar el foco” de un objeto específico de la ventana. La siguiente línea:

window.opener.focus()

le devuelve el foco a la ventana que abrió la ventana actual. Podemos quitar el foco de la ventana actual usando el código:

window.blur()

Además de lo anterior, hay una manera de posicionar la ventana en el escritorio (el espacio útil de la pantalla), usando para ello el método scroll, el cual nos permite desplazar la ventana hasta un punto de coordenadas de pixeles (x,y). La coordenada (0,0) siempre se refiere a la esquina superior izquierda de una ventana, de modo que:

window.scroll(0,0)

desplaza la ventana actual hacia la esquina superior izquierda. Podemos desplazar una ventana distinta de la ventana actual usando una instrucción como la siguiente (en este caso la ventana desplazada es la ventana principal):

window.opener.scroll(150,200)

Además de que es posible crear otras ventanas a partir del código JavaScript contenido en una ventana principal, también es posible subdividir el espacio disponible que hay dentro de una ventana en varias sub-ventanas llamadas marcos (conocidos en inglés como frames). Este es un tema manejado a partir de las convenciones HTML de una página Web ya que es en donde se definen los marcos mediantes las etiquetas <FRAMESET> y <FRAME>, aunque una vez creados los marcos estos pueden ser manipulados usando para ello código JavaScript.

La mejor manera de introducir al lector al concepto de los marcos es empezando con un ejemplo que el lector puede usar para familiarizarse mejor con el concepto. Empezaremos con el siguiente código que el lector deberá guardar como un archivo HTML bajo un nombre como “principal.html” (obsérvese que en este documento HTML fueron eliminadas por completo las etiquetas <BODY> que no deben aparecer en una página Web usada para especificar los marcos):

************** Archivo principal.html

<HTML>

<HEAD>

<TITLE>Página HTML para subdividir en marcos</TITLE>

</HEAD>

<FRAMESET ROWS="*,*" COLS="*,*">
   <FRAME NAME="superior_izquierdo" SRC="supizq.html">
   <FRAME NAME="superior_derecho" SRC="">
   <FRAME NAME="inferior_izquierdo" SRC="">
   <FRAME NAME="inferior_derecho" SRC="">
</FRAMESET>

</HTML>

**************

Una vez guardado lo anterior, se debe crear otro archivo que contendrá el siguiente código guardándolo bajo el nombre de archivo “supizq.html”:

************** Archivo supizq.html

<HTML>

    <HEAD>

    <TITLE>Prueba de Marcos</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
     
       function llenarMarco(nombremarco) {

          // Encontrar el objeto para el marco
          elMarco = parent[nombremarco];

          // Abrir y limpiar el documento del marco
          elMarco.document.open()

          // Crear algo de salida
          elMarco.document.write("<H1>Texto JavaScript</H1>");
          elMarco.document.write("<p>Este texto está en el marco ");
          elMarco.document.write(nombremarco + "</p>")
          }
       
    </SCRIPT>

    </HEAD>

    <BODY>

      <H1>Prueba de Marcos</H1>
      <FORM NAME="FORMULARIO">
         <input type="button" value="Superior derecho" onClick="llenarMarco('superior_derecho');">
         <input type="button" value="Inferior izquierdo" onClick="llenarMarco('inferior_izquierdo');">
         <input type="button" id="js" value="Inferior derecho" onClick="llenarMarco('inferior_derecho');">

      </FORM>
   
   </BODY>

</HTML>

**************

Ambos archivos se deben guardar en una misma carpeta (directorio). La acción se pone en marcha abriendo el archivo “principal.html”; al hacer esto aparecerá una ventana de navegador subdividida en cuatro regiones iguales: una región superior izquierda, una región superior derecha, una región inferior izquierda, y una región inferior derecha. En la ventana superior izquierda habrá tres botones que dirán: “Superior derecho”, “Inferior izquierdo” e “Inferior derecho”. Haciendo clic en el botón “Superior derecho” aparecerá dentro del marco superior derecho el texto:

Texto JavaScript

Este texto está en el marco superior_derecho
Haciendo clic en los otros dos botones (en cualquier orden) aparecerán mensajes de texto similares en los otros dos marcos, alusivos a la posición de cada marco dentro de la ventana.

El ejemplo que acabamos de ver nos permite formalizar el concepto de los marcos en un documento HTML manejado dede la perspectiva de JavaScript. Por debajo del objeto window, el objeto de mayor jerarquía posible, se tiene el objeto frame (el objeto “marco”, no se olvide que en JavaScript las minúsculas así como la capitalización en mayúsculas tiene que ser respetada). Una ventana puede tener varios marcos, y los marcos pueden tener cada uno sus propias barras de desplazamientos. Asimismo, cada marco tiene su propio domicilio URL.

En los albores de la Web, dos limitaciones importantes eran que los navegadores sólo podían mostrar un documento HTML a la vez en la ventana del navegador, y los sitios Web no podían abrir más ventanas de navegación en caso de ser necesario. Los marcos permiten subdividir la ventana de un navegador en secciones rectangulares distintas, cada una conteniendo un documento HTML diferente:




Esto a su vez permite crear una página Web (la ventana principal) con áreas distintas tales como tablas de contenidos, listar de hipervínculos, encabezados (banners), barras laterales de información, etcétera:




Las etiquetas que permiten subdividir una ventana de navegación y cargar un documento diferente en cada marco fueron introducidas por vez primera en el browser Netscape Navigator 2.0, y fueron incluídas en la convención HTML 4.01.

Un grupo de marcos (frameset) es un grupo de marcos definidos dentro de un documento enmarcado dentro de las etiquetas <FRAMESET>. El primer documento HTML que es necesario crear cuando se usan marcos es el documento en el que se define (o se definen) un grupo de marcos, como en el caso del archivo de ejemplo “principal.html” dado arriba. Es aquí en donde se define la distribución de los marcos y las direcciones URL de los documentos HTML a ser cargados inicialmente en cada marco. Cuando se usa en un documento HTML, la etiqueta <FRAMESET> reemplaza la etiqueta <BODY> como se muestra en el siguiente código:
<HTML>
   <HEAD>
      <TITLE>Título de la página</TITLE>
   </HEAD>
   <FRAMESET>
      ...Aquí es en donde se especifican los marcos de un grupo
   </FRAMESET>
</HTML>
Es importante entender cómo un documento HTML de enmarcado difiere de un documento HTML normal. Si se incluye una etiqueta <FRAMESET> en un documento HTML, no se puede incluír también una etiqueta <BODY>. Las dos etiquetas son mutuamente excluyentes. Más aún, no es permisible incluír en un documento de enmarcado otras etiquetas de formateo HTML, ni hipervínculos (exceptuando los que especifican con el atributo SRC), ni siquiera material textual.

Cuando se define una etiqueta <FRAMESET>, es necesario incluír uno de dos atributos como parte de la definición de la etiqueta. El primero de estos atributos es el atributo de columnas COLS cuya sintaxis es la siguiente:

<FRAMESET COLS="anchura de columna, anchura de columna, ..."

El atributo COLS le indica al navegador dividir la pantalla en un cierto número de marcos verticales, cuyas anchuras respectivas (de izquierda a derecha) están definidas por los valores anchura de columna separados por comas. Se puede definir la anchura de tres maneras: (1) explícitamente en pixeles, (2) como un porcentaje de la anchura total del conjunto de marcos, (3) con un asterisco (*). Cuando se usa el asterisco, el navegador asigna automáticamente tanto espacio como sea posible para el marco especificado. En el siguiente ejemplo, en la quinta línea del código se crea un marco izquierdo con una anchura de 100 pixeles, una columna media que ocupa el 50% de la anchura de la pantalla, y una columna derecha que usa todo el espacio remanente disponible:
<HTML>
   <HEAD>
      <TITLE>Tres columnas</TITLE>
   </HEAD>
   <FRAMESET COLS="100,50%,*">
      <FRAME SRC="COLIZQUIERDA.HTML">
      <FRAME SRC="COLMEDIA.HTML">
      <FRAME SRC="COLDERECHA.HTML">
   </FRAMESET>
</HTML>
El atributo de renglones ROWS funciona de modo parecido al atributo COLS, excepto que parte la pantalla en marcos separados horizontalmente en lugar de verticalmente. El siguiente código HTML subdivide la pantalla en dos marcos de igual altura:
<HTML>
   <HEAD>
      <TITLE>Dos renglones</TITLE>
   </HEAD>
   <FRAMESET ROWS="50%,50%">
      <FRAME SRC="RENGLONSUP.HTML">
      <FRAME SRC="RENGLONINF.HTML">
   </FRAMESET>
</HTML>
En el caso de que un navegador no dé soporte a marcos y descargue una página construída con marcos, lo único que verá el visitante será una página en blanco. Afortunadamente, para este tipo de situaciones, hay una etiqueta especial de bloque llamada <NOFRAMES> que permite incluír código HTML adicional como parte del documento de enmarcado. El código incluído dentro del bloque <NOFRAMES> no es mostrado por navegadores compatibles con marcos HTML, pero será mostrado por navegadores que no apoyan marcos:
<HTML>
   <HEAD>
      <TITLE>Manejo universal para marcos</TITLE>
   </HEAD>
   <FRAMESET>
      Aquí va el conjunto de marcos
   <NOFRAMES>
      Aquí va material alterno HTML ordinario
   </NOFRAMES>
   </FRAMESET>
</HTML>
   <FRAME SRC="ALTERNO.HTML">
   </FRAMESET>
</HTML>
En los ejemplos mostrados arriba, los bordes que separan los marcos son bordes gruesos. Podemos controlar la apariencia de los bordes o incluso hacer que no aparezcan usando los atributos BORDERCOLOR y FRAMEBORDER. Podemos asignar a BORDERCOLOR cualquier valor de color válido ya sea como un nombre predeterminado (como yellow) o como un valor hexadecimal como #CC44DD (véase el anexo “HTML, XML, XHTML”). Por su parte, FRAMEBORDER puede tomar dos valores posibles, 1 (para mostrar los bordes) ó 0 (para ocultar los bordes); por ejemplo:
<HTML>
   <HEAD>
      <TITLE>Atributos de la etiqueta FRAME</TITLE>
   </HEAD>
   <FRAMESET ROWS="*,*">
      <FRAME SRC="doc1.html">
      <FRAME FRAMEBORDER="1" BORDERCOLOR="#00FFAA" SRC="doc2.html">
      <FRAME SRC="doc3.html">
   </FRAMESET>
</HTML>
En el uso cotidiano, rara vez se encuentran los diseños básicos de enmarcado que se han definido arriba, y con frecuencia veremos enmarcados un poco más sofisticados como el siguiente:




Para lograr algo así, se recurre a lo que se conoce como el anidamiento de marcos:
<HTML>
   <HEAD>
      <TITLE>Anidamiento de enmarcados</TITLE>
   </HEAD>
   <FRAMESET COLS="125,*">
      <FRAME SRC="opciones.html">
         <FRAMESET ROWS="60,*">
            <FRAME SRC="texto1.html">
            <FRAME SRC="texto2.html">
         </FRAMESET>
   </FRAMESET>
</HTML>
El anidamiento mostrado es el más esencial para repartir la ventana principal en tres marcos, siendo las dos variantes:




Es posible crear a partir de los anidamientos básicos otros anidamientos aún más elaborados metiendo cinco o más marcos dentro de una misma página (lo cual puede ser contraproducente si se quiere que el visitante no batalle con la lectura e interpretación visual del contenido de la página Web), como el que produce el siguiente código:
<FRAMESET COLS="50%,*">
  <FRAMESET ROWS="50%,*">
    <FRAME SRC="frame1.html">
    <FRAME SRC="frame2.html">
  </FRAMESET>
  <FRAMESET ROWS="33%,33%,*">
    <FRAME SRC="frame3.html">
    <FRAME SRC="frame4.html">
    <FRAME SRC="frame5.html">
  </FRAMESET>
</FRAMESET>
De cualquier modo, antes de elaborar una página Web que incluya marcos anidados, el programador debería analizar otra opción de diseño que ofrece mayor variedad y una mejor capacidad de control sobre la apariencia de un documento HTML sofisticado (como la página de un periódico online): las Hojas de Estilos en Cascada CSS (Cascading Style Sheets), la forma recomendada para controlar la apariencia de una página. Al inicio del tecer milenio, la transición hacia las CSS adquirió importancia en virtud de que con la introducción de HTML 5 algunos de los atributos de las etiquetas HTML ya no funcionan como antes porque ya no son reconocidos.

Volviendo nuevamente a JavaScript y su manejo de marcos, las propiedades mínimas del objeto frame (marco) que se pueden encontrar apoyadas en los navegadores de mayor uso son las siguientes:
frames.- Un arreglo (array) que contiene todos los marcos que hay en una ventana (más abajo estudiaremos en mayor detalle el asunto de los arreglos).

Name.- El atributo NAME de la etiqueta <FRAME>

Length.- El número de marcos hijo dentro de un marco

Parent.- La ventana o el marco que contiene el conjunto de marcos (frameset) actual

self.- El marco actual

window.- El marco actual
Es posible agregarle otras características a cada marco, tales como color de fondo o inclusive una imagen de fondo. Los constructores visuales de páginas Web tales como el programa FrontPage de Microsoft y otros similares permiten elaborar cada marco de un modo sofisticado. De cualquier modo, el programador Web no debe olvidar en un solo momento que todas las páginas Web creadas con la ayuda de editores HTML siempre tienen un código fuente HTML que puede ser inspeccionado y modificado según se requiera. Y cada marco, de manera predeterminada, tiene como mínimo su propio un par de etiquetas <HTML> Y </HTML> que corresponden a la página Web hacia la cual conecta, entre las cuales el programador puede meter lo que quiera tal y como lo hace con cualquier página Web ordinaria, de modo tal que las posibilidades están limitadas únicamente por la imaginación del programador.

Ahora veamos en mayor detalle el tema de los arreglos en JavaScript.

Todos estamos familiarizados con los archiveros, esos gabinetes metálicos en donde guardamos archivos que suelen ser agrupados dentro de carpetas. Hay quienes se las pueden arreglar con una pila desordenada de papeles y todo tipo de documentos arrumbados en un rincón, logrando de alguna manera encontrar lo que necesitan sin tomarse horas para ello al buscar algo entre esa pila desordenada. Sin embargo, no ocurre lo mismo con una computadora, los datos tienen que estar bien ordenados o al menos deben ser localizables de alguna manera metódica, de lo contrario se pueden dar por perdidos.

Al igual que un archivero, un arreglo o array (de su traducción al inglés en donde se pronuncia como “arrei”) es una forma de organizar ciertos datos en grupos. Un arreglo puede contener cualquier cantidad de elementos, y cada elemento puede ser cualquier tipo de datos, incluídos otros arreglos, en cuyo caso estaríamos hablando de un arreglo de arreglos.

Una carpeta como “Mis Documentos” (My Documents) en un sistema operativo Windows es un ejemplo de un arreglo que puede contener varios tipos de archivos (documentos de texto, imágenes fotográficas, programas ejecutables, archivos de música, etc.) e inclusive puede contener otras carpetas que a su vez pueden contener otros archivos y carpetas.

La capacidad para poder crear arreglos dinámicamente no existía en la primera versión de JavaScript cuando apareció por vez primera como JavaScript 1.0. Esta importante omisión fue subsanada en la subversión posterior JavaScript 1.1, la cual introdujo tantas mejoras (ampliando además las propiedades y métodos a los objetos JavaScript ya predefinidos) que hay quienes opinan que debería de haber sido nombrada JavaScript 2.0.

Es muy sencillo implementar un arreglo en JavaScript que pueda contener cualquier cantidad de elementos. Cada elemento tiene un número de índice, un número entero que por definición empieza a partir de cero: 0, 1, 2, 3, ... , que marca su posición ordenada en el arreglo. La sintaxis para describir un arreglo en JavaScript es la siguiente:


arreglo[id] = valor

Así, un arreglo que describa razas de perros puede escribirse de la manera siguiente:

   raza[0] = "Collie"
   raza[1] = "Doberman"
   raza[2] = "Pastor Alemán"
   raza[3] = "Pomeranio"

... y así sucesivamente.

De este modo, un arreglo es como un archivero cuyo contenido está asociado a índices numéricos, lo cual nos permite acceder con rapidez a los datos del archivero. En una página Web, se pueden codificar varios arreglos en los programas JavaScript que contengan datos pertinentes para la función de la página. Supongamos, por ejemplo, que se tiene en una página Web un formulario (la creación de formularios con las etiquetas <FORM> está descrita en otra entrada) para recabar datos del usuario (nombre, apellido, edad, lugar de residencia, profesión, correo electrónico, etc.) Podemos almacenar todos estos elementos de información en un arreglo llamado “datosusuario” que podrá tener el siguiente aspecto:

   datosusuario[0] = "Gilberto"
   datosusuario[1] = "Gómez"
   datosusuario[2] = 45
   datosusuario[3] = "Chihuahua"
   datosusuario[4] = "Ingeniero de Calidad"
   datosusuario[5] = "gilbertogomez@hotmail.com"

Pero para poder introducir datos en un arreglo, primero es necesario que exista el arreglo. En JavaScript se define un arreglo de la siguiente manera:


nombrearreglo = new Array()

en donde nombrearreglo es el nombre del arreglo. Opcionalmente, podemos definir los elementos del arreglo al tiempo en que creamos el arreglo:

raza = new Array ("Collie", "Doberman")

Obsérvese que para crear un arreglo en JavaScript usamos la misma palabra reservada new que se utiliza para crear ejemplares de objetos en JavaScript. Esto en virtud de que en JavaScript, siguiente la filosofía y metodología de la programación orientada-a-objetos, un arreglo es un objeto. La palabra reservada “Array()” proporciona el “esqueleto”, la estructura básica, y con la palabra reservada new se crea un ejemplar de dicho objeto, en este caso el ejemplar “raza” del objeto Array.

A continuación se tiene un ejemplo sencillo del uso de arreglos en JavaScript:
<HTML>

<HEAD>

<TITLE>Ejemplo de Arreglos en JavaScript</TITLE>

<SCRIPT LANGUAGE="JavaScript">
   raza = new Array();
   raza[0] = "Collie";
   raza[1] = "Doberman";
   raza[2] = "Pomeranian";
   document.write(raza[0] + "<BR>");
   document.write(raza[1]+  "<BR>");
   document.write(raza[2] + "<BR>");
</SCRIPT>

</HEAD>

<BODY>

</BODY>

</HTML>
Si se guarda el código anterior bajo un archivo con la extensión “html” o “htm” y se abre el archivo con cualquier navegador actualizado, se imprimirá lo siguiente en la pantalla:

   Collie
   Doberman
   Pomeranian

A continuación se tiene una versión ligeramente modificada de lo anterior que nos muestra la manera en la cual se puede usar un bucle for para accesar uno por uno los elementos de un arreglo (en este caso, para ir imprimiendo cada elemento en la pantalla):
<HTML>

    <HEAD>

    <TITLE>Otro ejemplo de Arreglos en JavaScript</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
       raza = new Array();
       raza[0] = "Collie";
       raza[1] = "Doberman";
       raza[2] = "Pomeranian";
       for (i=0 ; i<=2; i++) {
       document.write(raza[i] + "<BR>");
       }
    </SCRIPT>

</HEAD>

<BODY>

</BODY>

</HTML>
Si se guarda el código anterior bajo un archivo con la extensión “html” o “htm” y se abre el archivo con cualquier navegador actualizado, nuevamente se imprimirá lo siguiente en la pantalla:

   Collie
   Doberman
   Pomeranian

Una de las propiedades del objeto Array es la propiedad length, definida por la cantidad de elementos que contiene un arreglo. Si un array contiene cien elementos, entonces la propiedad length tendrá un valor de cien. Para poder accesar dicho valor, al igual que en los demás casos, usamos el operador punto. En el caso del arreglo datosusuario, usando el operador punto se obtiene:

datosusuario.length = 6

O sea que datosusuario contiene el valor 6, y por lo tanto el arreglo contiene seis elementos. En el programa dado arriba, podemos ver la propiedad length en acción agregando una línea adicional:
<HTML>

    <HEAD>

    <TITLE>Ejemplo del uso de la propiedad length</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
       raza = new Array();
       raza[0] = "Collie";
       raza[1] = "Doberman";
       raza[2] = "Pomeranian";
       for (i=0 ; i<=2; i++) {
       document.write(raza[i] + "<BR>");
       }
     
       var numero = raza.length;
       document.write("Hay " + numero + " elementos");
    </SCRIPT>

</HEAD>

<BODY>

</BODY>

</HTML>
Si se guarda el código anterior bajo un archivo con la extensión “html” o “htm” y se abre el archivo con cualquier navegador actualizado, nuevamente se imprimirá lo siguiente en la pantalla:

   Collie
   Doberman
   Pomeranian
   Hay 3 elementos

Ya hemos visto que un objeto puede contener no solo propiedades sino métodos también, y el objeto Array posee tres métodos que nos permiten manipular los elementos del arreglo. los cuales son:

join()

reverse()

sort()

El método join() es un método que concatena todos los elementos de un arreglo para formar una sola hilera, esto es, para formar un valor de cadena (una hilera) largo. Por ejemplo, si se empieza con:

raza = new Array ("Chihuahua","Collie")

entonces si escribimos raza.join() en una instrucción de asignación de variable como ésta:

perros = raza.join()

la variable de hilera “perros” contendrá la hilera:

"Chihuahua,Collie"

De manera predeterminada, el método join() usa comas para separar elementos dentro de la hilera de texto, aunque es fácil especificar un delimitador distinto usando los paréntesis para el argumento de join(). Por ejemplo, con la siguiente instrucción:

perros = raza.join(" ")

los elementos serán separados usando un espacio en blanco en lugar de una coma, produciendo la hilera:

"Chihuahua Collie"

El método reverse() simplemente invierte las posiciones de los elementos dentro del objeto Array. Supóngase que se tiene el arreglo de cinco elementos llamado “raza”:

   raza[0] = "Chihuahua"
   raza[1] = "Collie"
   raza[2] = "Doberman"
   raza[3] = "Pastor Alemán"
   raza[4] = "Pomeranio"

Entonces la invocación del método reverse() sobre el objeto tipo Array “raza”:

raza.reverse()

hará que el arreglo quede de la siguiente manera:

   raza[0] = "Pomeranio"
   raza[1] = "Pastor Alemán"
   raza[2] = "Doberman"
   raza[3] = "Collie"
   raza[4] = "Chihuahua"

Por último, el método sort() es usado para ordenar los elementos de un arreglo, ya sea alfabéticamente o numéricamente, según sea el caso. En el siguiente arreglo:

   nombre[0] = "Regina"
   nombre[1] = "Dafne"
   nombre[2] = "Armando"
   nombre[3] = "Shanik"
   nombre[4] = "Andrea"

la operación:

nombre.sort()

hará que el arreglo quede de la siguiente manera:

   nombre[0] = "Andrea"
   nombre[1] = "Armando"
   nombre[2] = "Dafne"
   nombre[3] = "Regina"
   nombre[4] = "Shanik"

A modo de ejemplo, el siguiente programa nos muestra la manera en la cual actúa el método sort():
<HTML>

    <HEAD>

    <TITLE>Ejemplo del uso del método sort()</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
       raza = new Array();
       raza[0] = "Pomeranian";
       raza[1] = "Doberman";
       raza[2] = "Collie";
       raza[3] = "Pitbull";
       raza.sort();
       for (i=0 ; i<=3; i++) {
       document.write(raza[i] + "<BR>");
       }

    </SCRIPT>

</HEAD>

<BODY>

</BODY>

</HTML>
Si se guarda el código anterior bajo un archivo con la extensión “html” o “htm” y se abre el archivo con cualquier navegador actualizado, se imprimirá lo siguiente en la pantalla:

    Collie
    Doberman
    Pitbull
    Pomeranian

Es posible diseñar un algoritmo de reordenamiento a la medida del usuario con el método sort(), con la invocación de la función:

nombreArray.sort(funcsort)

empleando el algoritmo que se codifique la función que podemos llamar como funcsort (o cualquier otro nombre que el usuario le quiera poner). Generalmente hablando, estos refinamientos no deben ser necesarios, y el algoritmo predefinido en JavaScript para el método sort() funciona satisfactoriamente en la mayoría de los casos.

En virtud de que el arreglo básico es unidimensional, el concepto de arreglo es sencillo. Ya se había mencionado que se posible crear un arreglo cuyos elementos sean a su vez arreglos. ¿Pero cómo podemos lograr tal cosa? Pues de manera sencilla, construyéndolo bidimensionalmente. En un arreglo bidimensional cada elemento puede ser otro arreglo diferente por derecho propio, y así cada elemento de un arreglo puede a su vez ser un arreglo con sus propios elementos (los cuales también pueden ser otros arreglos, y así sucesivamente, en cuyo caso estaríamos hablando de un arreglo multidimensional). Los matemáticos están acostumbrados a manejar tal concepto en un caso especial en el cual un arreglo bidimensional contiene como elementos varios arreglos con la misma cantidad de elementos, y ese tipo especial de arreglo bidimensional se llama matriz, como en el siguiente ejemplo que muestra una matriz 5×5:


La matriz dada arriba puede ser vista de dos maneras diferentes, ya sea como un arreglo columnar de arreglos horizontales llamados vectores renglón:


o como un arreglo horizontal de vectores columna:


Podemos ver que los vectores renglón que forman parte del arreglo matricial son:
A = (5, 4, 3, 7, 1)
B = (1, 0, 8, 2, 3)
C = (2, 1, 4, 6, 9)
D = (4, 6, 5, 0, 8)
E = (7, 2, 3, 9, 1)
mientras que los vectores columna que forman parte del arreglo matricial son:
P = (5, 1, 2, 4, 7)
Q = (4, 0, 1, 6, 2)
R = (3, 8, 4, 5, 3)
S = (7, 2, 6, 0, 9)
T = (1, 3, 9, 8, 1)
Para poder crear un arreglo bidimensional, empezamos creando un arreglo unidimensional de la manera usual:

nombreArray = new Array()

Una vez creado el arreglo “nombreArray”, podemos meter otro arreglo dentro de dicho arreglo asignando new Array() a un elemento del arreglo ya existente, por ejemplo nombreArray[0]:

nombreArray[0] = new Array()

Opcionalmente, podemos definir los elementos del arreglo dentro del arreglo “nombreArray” al mismo tiempo en que creamos el arreglo, por ejemplo:

nombreArray[0] = new Array ("Collie", "Doberman")

Nos referimos a un arreglo bidimensional usando ambos índices. En el caso que se acaba de mostrar:

nombreArray[0][0] = "Collie"

nombreArray[0][1] = "Doberman"

Como un ejemplo de lo anterior, supóngase que se tiene un grupo escolar de secundaria en el cual hay dos listas de hombres y mujeres estudiantes:
Carlos Domínguez
Arnulfo Ibarra
Jesús Romero
Guillermo Ponce
Adrián Lara
Francisco Sarabia

Marisela Sherman
Gilda Beutelspacher
Mayté Gaos
Teresa Godoy
Un programa JavaScript en el cual se crea un arreglo bidimensional manteniendo separados ambos grupos, y con el cual se imprime la lista de todos los estudiantes juntos es el siguiente:
<HTML>

    <HEAD>

    <TITLE>Ejemplo de un Arreglo bidimensional</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
     
       // Creación del arreglo básico
     
       estudiantes = new Array();
     
       // Creación de arreglos dentro del arreglo
     
       estudiantes[0] = new Array();
       estudiantes[1] = new Array();
     
       // Inicialización del arreglo bidimensional
     
       for (i=0; i<=1; i++) {
           for (j=0 ; j<=5; j++) {
               estudiantes[i][j] ="";
           }
       }

       // Asignación de elementos al arreglo
       // bidimensional
           
       estudiantes[0][0] = "Carlos Domínguez";
       estudiantes[0][1] = "Arnulfo Ibarra";
       estudiantes[0][2] = "Jesús Romero";
       estudiantes[0][3] = "Guillermo Ponce";
       estudiantes[0][4] = "Adrián Lara";
       estudiantes[0][5] = "Francisco Sarabia";

       estudiantes[1][0] = "Marisela Sherman";
       estudiantes[1][1] = "Gilda Beutelspacher";
       estudiantes[1][2] = "Mayté Gaos";
       estudiantes[1][3] = "Teresa Godoy";
     
       // Impresión de los elementos del arreglo
       // bidimensional
     
       for (j=0; j<=5; j++) {
           for (i=0 ; i<=1; i++) {
           document.write(estudiantes[i][j] + "<BR>");
           }
       }

    </SCRIPT>

</HEAD>

<BODY>

</BODY>

</HTML>
En el programa podemos ver que los nombres de los estudiantes fueron asignados de la siguiente manera según su sexo:
estudiantes[0][0] = "Carlos Domínguez"
estudiantes[0][1] = "Arnulfo Ibarra"
estudiantes[0][2] = "Jesús Romero"
estudiantes[0][3] = "Guillermo Ponce"
estudiantes[0][4] = "Adrián Lara"
estudiantes[0][5] = "Francisco Sarabia"

grupo3A[1][0] = "Marisela Sherman"
grupo3A[1][1] = "Gilda Beutelspacher"
grupo3A[1][2] = "Mayté Gaos"
grupo3A[1][3] = "Teresa Godoy"
A continuación se presenta una aplicación más sofisticada de arreglos bidimensionales en JavaScript, un ejemplo que pudiéramos considerar como una pequeña “mini base de datos” (para la entrada de datos se usa un formulario creado con las etiquetas <FORM> ... </FORM>, siendo éste un tema cubierto en otra entrada):



<HTML>

    <HEAD>

    <TITLE>Desempeños escolares</TITLE>

    <SCRIPT LANGUAGE="JavaScript">
     
       function init() {
     
          // Variable de índice inicializada
          // a cero
       
          recidx = 0;
       
          // Creación del arreglo básico
       
          record = new Array();
       }
     
       function agregarReg() {
     
       // Creación de arreglo bidimensional
     
       record[recidx] = new Array();
     
       // Entrada de datos al arreglo bidimensional
     
       record[recidx][0] = document.bio.nombre.value;
       record[recidx][1] = document.bio.apellido.value;
       record[recidx][2] = document.bio.edad.value;
       record[recidx][3] = document.bio.sexo[0].checked;
       record[recidx][4] = document.bio.nivel.selectedIndex;
     
       // Incremento de la variable contadora para la
       // entrada del siguiente registro
     
       recidx++;
     
       // Limpieza de campos para preparar la siguiente
       // entrada de datos
     
       document.bio.clear.click();
       }
     
       function verReg() {
         viewwin = window.open("","ViewRecords", "scrollbars=yes, width=640, height=400");
         viewwin.document.writeln("<H2>Vista de "+ recidx
           + " Registro(s) Actual(es)</H2> <br>");
         
         for (var j=0; j<recidx; j++) {
           if (record[j][3]==true) {sexo="hombre"}
             else {sexo="mujer"} ;
           viewwin.document.write("<H3>" + record[j][0] + " " + record[j][1] + "</H3>");
           viewwin.document.write("<H4><i>Edad:</i> " + record[j][2] +
             "<br><i>Sexo:</i>" + sexo + "<br><i>Nivel de desempeño:</i> " + record[j][4] + "<p>");
            }
         
         viewwin.document.writeln("<p><form><input type=button value='Cerrar Vista de Registros' onClick='window.close()'></form>");
       }
         
</SCRIPT>

</HEAD>

<BODY onLoad="init()">
<p><H2>Registro de Desempeños Escolares</H2></p>

<p>Para agregar un registro, complétense los siguientes campos y hágase clic en "Agregar Registro". <br>
Para ver todos los registros actuales, hágase clic en "Ver Registros".</p>

<p>

<FORM NAME=bio>
<p>
Nombre<input type="text" size="10" name="nombre">
Apellido<input type="text" size="10" name="apellido">
Edad<input type="text" size="3" name="edad">
</p>

<p>
<input type="radio" checked name="sexo">Hombre<br>
<input type="radio" name="sexo">Mujer
</p>

<p>
Desempeño académico:<br>
<select name="nivel" size="5">
   <option>Malo (5 o menos) </option>
   <option>Mínimo (6)</option>
   <option>Regular (7)</option>
   <option>Bueno (8)</option>
   <option>Muy bueno (8 o más)</option>
</select>
</p>

<p>
<input type="button" name="add" value="Agregar Registros" onClick="agregarReg()">
<input type="reset" name="clear" value="Limpiar Registros">
<input type="button" name="view" value="Ver Registros" onClick="verReg()">
</p>
</FORM>

<p>
<p><i>Nota: </i>La vista de registros se abre en una nueva ventana</p>

</BODY>

</HTML>



Este programa en JavaScript implementa lo que puede ser considerado como una pequeña base de datos. Si se guarda el código anterior bajo un archivo con la extensión “html” o “htm” y se abre el archivo con cualquier navegador actualizado, aparecerán unos campos de texto para introducir el nombre, el apellido y la edad de un estudiante, un par de botones para escoger el sexo del estudiante, y una tabla para escoger el desempeño escolar del estudiante que en base a sus calificaciones le asigna una de cinco categorías que van desde un desempeño escolar pobre (nivel 0) hasta un desempeño escolar muy bueno (nivel 4). Una vez que se oprime el botón “Agregar Registro”, se limpian los campos de texto al ser agregado el registro a la base de datos. Se pueden agregar varias personas, y una vez que se tengan unas tres o cuatro personas agregadas al oprimir el botón “Ver Registros” aparecerá en una ventana nueva de navegador (por separado) la lista completa de personas que hay en la base de datos.

El programa usa JavaScript para definir tres funciones: una función de inicialización init() que crea un arreglo básico (unidimensional), la función agregarReg() para ir agregando un registro nuevo a la base de datos con la información en forma de array de cada persona, creándose con ello un arreglo cuyos elementos serán una lista creciente de arreglos, y la función verReg() para ver en una ventana nueva los datos de cada persona. Podemos ver en el programa que:

   record[ j][0] es el nombre de la persona  j
   record[ j][1] es el apellido de la persona  j
   record[ j][2] es la edad de la persona  j
   record[ j][3] es el sexo de la persona  j
   record[ j][4] es el nivel de desempeño de la persona  j

Con modificaciones mínimas, el programa anterior puede ser ampliado para dar entrada a otro tipo de datos. La desventaja es que, por razones de seguridad y para protección del usuario, JavaScript no permite que se guarde nada en el disco duro del usuario. Sin embargo, los datos se pueden enviar a un servidor Web que se puede encargar de ir almacenando la información que se le envíe, lo cual requiere de elementos adicionales de interactividad que son tratados en mayor detalle en la entrada titulada “La interfaz cliente-servidor”.