HTML5 puede ser imaginado como un edificio soportado por tres grandes columnas: HTML, CSS y Javascript. Ya hemos estudiado los elementos incorporados en HTML y las nuevas propiedades que hacen CSS la herramienta ideal para diseñadores. Ahora es momento de develar lo que puede ser considerado como uno de los pilares más fuertes de esta especificación: la relevancia de Javascript.
Javascript es un lenguaje interpretado usado para múltiples propósitos pero solo considerado como un complemento hasta ahora. Una de las innovaciones que ayudó a cambiar el modo en que vemos Javascript fue el desarrollo de nuevos motores de interpretación, creados para acelerar el procesamiento de código.
La clave de los motores más exitosos fue transformar el código Javascript en código máquina para lograr velocidades de ejecución similares a aquellas encontradas en aplicaciones de escritorio. Esta mejorada capacidad permitió superar viejas limitaciones de rendimiento y confirmar el lenguaje Javascript como la mejor opción para la web.
Para aprovechar esta prometedora plataforma de trabajo ofrecida por los nuevos navegadores, Javascript fue expandido en relación con portabilidad e integración. A la vez, interfaces de programación de aplicaciones (APIs) fueron incorporadas por defecto en cada navegador para asistir al lenguaje en funciones elementales. Estas nuevas APIs (como Web Storage, Canvas, y otras) son interfaces para librerías incluidas en navegadores.
La idea es hacer disponible poderosas funciones a través de técnicas de programación sencillas y estándares, expandiendo el alcance del lenguaje y facilitando la creación de programas útiles para la web.
En este capítulo vamos a estudiar cómo incorporar Javascript dentro de nuestros documentos HTML y veremos las incorporaciones recientes a este lenguaje con la intención de prepararnos para el resto del articulo.
IMPORTANTE:
Nuestro acercamiento a Javascript en este libro es introductorio. Al igual que con CSS, solo vamos a repasar las técnicas que necesitamos entender para implementar los ejemplos de próximos capítulos. Trabajaremos sobre temas complejos, pero solo usando un mínimo de código necesario para aprovechar estas nuevas características. Si necesita expandir sus conocimientos sobre este lenguaje, visite nuestro sitio web y siga los enlaces correspondientes a este capítulo.
Relevancia de JavaScript: Incorporación del lenguaje
Siguiendo los mismos lineamientos que en CSS, existen tres técnicas para incorporar código Javascript dentro de HTML. Sin embargo, al igual que en CSS, solo la inclusión de archivos externos es la recomendada a usar en HTML5.
IMPORTANTE:
En este capítulo introducimos nuevas características así como técnicas básicas necesarias para entender los ejemplos del libro. Si usted se encuentra familiarizado con esta información siéntase libre de obviar las partes que ya conoce.
En línea
Esta es una técnica simple para insertar Javascript en nuestro documento que se aprovecha de atributos disponibles en elementos HTML. Estos atributos son manejadores de eventos que ejecutan código de acuerdo a la acción del usuario.
Los manejadores de eventos más usados son, en general, los relacionados con el ratón, como por ejemplo onclick, onMouseOver u onMouseOut. Sin embargo, encontraremos sitios web que implementan eventos de teclado y de la ventana, ejecutando acciones luego de que una tecla es presionada o alguna condición en la ventana del navegador cambia (por ejemplo, onload u onfocus).
<!DOCTYPE html>
<html lang=”es”>
<head>
<title>Este texto es el título del documento</title>
</head>
<body>
<div id=”principal”>
<p onclick=”alert(‘hizo clic!’)”>Hacer Clic</p>
<p>No puede hacer clic</p>
</div>
</body>
</html>
Usando el manejador de eventos onclick en el Listado 4-1, un código es ejecutado cada vez que el usuario hace clic con el ratón sobre el texto que dice “Hacer Clic”. Lo que el manejador onclick está diciendo es algo como: “cuando alguien haga clic sobre este elemento ejecute este código” y el código en este caso es una función predefinida en Javascript que muestra una pequeña ventana con el mensaje “¡hizo clic!”.
Cambio de manejador
Intente cambiar el manejador onclick por onMouseOver, por ejemplo, y verá cómo el código es ejecutado solo pasando el puntero del ratón sobre el elemento. El uso de Javascript dentro de etiquetas HTML está permitido en HTML5, pero por las mismas razones que en CSS, esta clase de práctica no es recomendable. El código HTML se extiende innecesariamente y se hace difícil de mantener y actualizar. Así mismo, el código distribuido sobre todo el documento complica la construcción de aplicaciones útiles.
Nuevos métodos y técnicas fueron desarrollados para referenciar elementos HTML y registrar manejadores de eventos sin tener que usar código en línea (inline). Volveremos sobre esto y aprenderemos más sobre eventos y manejadores de eventos más adelante en este capítulo.
Embebido
Para trabajar con códigos extensos y funciones personalizadas debemos agrupar los códigos en un mismo lugar entre etiquetas <script>. El elemento <script> actúa exactamente igual al elemento <style> usado para incorporar estilos CSS. Nos ayuda a organizar el código en un solo lugar, afectando a los elementos HTML por medio de referencias.
Del mismo modo que con el elemento <style>, en HTML5 no debemos usar ningún atributo para especificar lenguaje. Ya no es necesario incluir el atributo type en la etiqueta <script>. HTML5 asigna Javascript por defecto.
<!DOCTYPE html>
<html lang="es">
<head>
<title>Este texto es el título del documento</title>
<script>
function mostraralerta(){
alert('hizo clic!');
}
function hacerclic(){
document.getElementsByTagName('p')[0].onclick=mostraralerta;
}
window.onload=hacerclic;
</script>
</head>
<body>
<div id=”principal”>
<p>Hacer Clic</p>
<p>No puede hacer Clic</p>
</div>
</body>
</html>
El elemento < script > y su contenido pueden ser posicionados en cualquier lugar del documento, dentro de otros elementos o entre ellos. Para mayor claridad, recomendamos siempre colocar sus códigos Javascript en la cabecera del documento (como en el ejemplo del Listado 4-2) y luego referenciar los elementos a ser afectados usando los métodos Javascript apropiados para ese propósito.
Actualmente existen tres métodos disponibles para referenciar elementos HTML desde Javascript:
- getElementsByTagName (usado en el Listado 4-2) referencia un elemento por su nombre o palabra clave
- getElementById referencia un elemento por el valor de su atributo id
- getElementsByClassName es una nueva incorporación que nos permite referenciar un elemento por el valor de su atributo class.
Incluso si seguimos la práctica recomendada (posicionar el código dentro de la cabecera del documento), una situación debe ser considerada: el código del documento es leído de forma secuencial por el navegador y no podemos referenciar un elemento que aún no ha sido creado.
En el Listado 4-2, el código es posicionado en la cabecera del documento y es leído por el navegador previo a la creación del elemento < p > que estamos referenciando. Si hubiésemos intentado afectar el elemento < p > directamente con una referencia, hubiéramos recibido un mensaje de error anunciando que el elemento no existe. Para evitar este problema, el código fue convertido a una función llamada mostraralerta(), y la referencia al elemento < p > junto con el manejador del evento fueron colocados en una segunda función llamada hacerclic().
Las funciones son llamadas desde la última línea del código usando otro manejador de eventos (en este caso asociado con la ventana) llamado onload. Este manejador ejecutará la función hacerclic() cuando el documento sea completamente cargado y todos los elementos creados.
Análisis: ejecución del documento del Listado 4-2
Primero las funciones Javascript son cargadas (declaradas) pero no ejecutadas. Luego los elementos HTML, incluidos los elementos < p >, son creados. Y finalmente, cuando el documento completo es cargado en la ventana del navegador, el evento load es disparado y la función hacerclic() es llamada.
En esta función, el método getElementsByTagName referencia todos los elementos < p >. Este método retorna un arreglo (array) conteniendo una lista de los elementos de la clase especificada encontrados en el documento. Sin embargo, usando el índice [0] al final del método indicamos que solo queremos que el primer elemento de la lista sea retornado.
Una vez que este elemento es identificado, el código registra el manejador de eventos onclick para el mismo. La función mostraralerta() será ejecutada cuando el evento click es disparado sobre este elemento mostrando el mensaje “hizo clic!”.
Puede parecer mucho código y trabajo para reproducir el mismo efecto logrado por una simple línea en el ejemplo del Listado 4-1. Sin embargo, considerando el potencial de HTML5 y la complejidad alcanzada por Javascript, la concentración del código en un único lugar y la apropiada organización representa una gran ventaja para nuestras futuras implementaciones y para hacer nuestros sitios web y aplicaciones fáciles de desarrollar y mantener.
Conceptos básicos:
Una función es un código agrupado que es ejecutado solo cuando la función es invocada (activada o llamada) por su nombre. Normalmente, una función es llamada usando su nombre y algunos valores encerrados entre paréntesis (por ejemplo, hacerclic(1,2)). Una excepción a esta sintaxis es usada en el Listado 4-2.
En este código no usamos paréntesis porque estamos pasando al evento solo la referencia a la función, no el resultado de su ejecución. Para aprender más sobre funciones Javascript, visite nuestro sitio web y siga los enlaces correspondientes a este capítulo.
Archivos externos
Los códigos Javascript crecen exponencialmente cuando agregamos nuevas funciones y aplicamos algunas de las APIs mencionadas previamente. Códigos embebidos incrementan el tamaño de nuestros documentos y los hacen repetitivos (cada documento debe volver a incluir los mismos códigos).
Para reducir los tiempos de descarga, incrementar nuestra productividad y poder distribuir y reusar nuestros códigos en cada documento sin comprometer eficiencia, recomendamos grabar todos los códigos Javascript en uno o más archivos externos y llamarlos usando el atributo src:
<!DOCTYPE html>
<html lang="es">
<head>
<title>Este texto es el título del documento</title>
<script src=”micodigo.js”></script>
</head>
<body>
<div id=”principal”>
<p>Hacer Clic</p>
<p>No puede hacer Clic</p>
</div>
</body>
</html>
El elemento < script > en el Listado 4-3 carga los códigos Javascript desde un archivo externo llamado micodigo.js. De ahora en más, podremos insertar nuestros códigos en este archivo y luego incluir el mismo en cualquier documento de nuestro sitio web que lo necesite. Desde la perspectiva del usuario, esta práctica reduce tiempos de descarga y acceso a nuestro sitio web, mientras que para nosotros simplifica la organización y facilita el mantenimiento.
Hágalo usted mismo:
Copie el código del Listado 4-3 dentro del archivo HTML previamente creado. Cree un nuevo archivo de texto vacío que se llame micodigo.js y copie en su interior el código Javascript del Listado 4-2. Tenga en cuenta que solo el código entre las etiquetas es el que se debe copiar, pero sin incluir las etiquetas mismas. </p>
Nuevos Selectores
Como vimos anteriormente, los elementos HTML tienen que referenciarse desde Javascript para que puedan afectarse por el código. Si recuerda de previos capítulos, CSS, y especialmente CSS3, ofrece un poderoso sistema de referencia y selección que no tiene comparación con los pocos métodos provistos por Javascript para este propósito.
Los métodos getElementById, getElementsByTagName y getElementsByClassName no son suficientes para contribuir a la integración que este lenguaje necesita y sostener la relevancia que posee dentro de la especificación de HTML5. Para elevar Javascript al nivel que las circunstancias requieren, se incorporaron nuevas alternativas. Desde ahora podemos seleccionar elementos HTML aplicando toda clase de selectores CSS por medio de los nuevos métodos querySelector() y querySelectorAll().
querySelector()
Este método retorna el primer elemento que concuerda con el grupo de selectores especificados entre paréntesis. Los selectores se declaran usando comillas y la misma sintaxis CSS, como en el siguiente ejemplo:
function hacerclic(){
document.querySelector(“#principal p:first-
child”).onclick=mostraralerta;
}
function mostraralerta(){
alert('hizo clic!');
}
window.onload=hacerclic;
En el Listado 4-4, el método getElementsByTagName que se usó anteriormente se reemplazó por querySelector(). Los selectores para esta consulta en particular están referenciando al primer elemento, hijo del elemento que se identifica con el atributo id y el valor main.
Debido a que ya explicamos que este método solo retorna el primer elemento encontrado, probablemente notará que la pseudo clase first-child es redundante. El método querySelector() en nuestro ejemplo retornará el primer elemento < p > dentro de < div > que es, por supuesto, su primer hijo.
El propósito de este ejemplo es mostrarle que querySelector() acepta toda clase de selectores válidos CSS y ahora, del mismo modo que en CSS, Javascript también provee herramientas importantes para referenciar cada elemento en el documento.
Varios grupos de selectores pueden declararse al separarlos por coma. El método querySelector() retornará el primer elemento que concuerde con cualquiera de ellos.
querySelectorAll()
En lugar de uno, el método querySelectorAll() retorna todos los elementos que concuerdan con el grupo de selectores declarados entre paréntesis. El valor retornado esun arreglo (array) conteniendo cada elemento encontrado en el orden en el que aparecen en el documento.
function hacerclic(){
var lista=document.querySelectorAll(“#principal p”);
lista[0].onclick=mostraralerta;
}
function mostraralerta(){
alert('hizo clic!');
}
window.onload=hacerclic;
El grupo de selectores especificados en el método querySelectorAll() del Listado 4-5 encontrará cada elemento < p > en el documento HTML del listado 4-3 que es hijo del elemento < div >. Luego de la ejecución de esta primera línea, el array lista tendrá dos valores: una referencia al primer elemento < p > y una referencia al segundo elemento < p >.
Debido a que el índice de cada array comienza por 0, en la próxima línea el primer elemento encontrado es referenciado usando corchetes y el valor 0 (lista[0]). Note que este ejemplo no muestra el potencial de querySelectorAll().
Normalmente se utiliza para afectar a varios elementos y no solo uno, como en este caso
Para interactuar con una lista de elementos retornados por este método, podemos utilizar un bucle for:
function hacerclic(){
var lista=document.querySelectorAll(“#principal p”);
for(var f=0; f<lista.length; f++){
lista[f].onclick=mostraralerta;
}
}
function mostraralerta(){
alert('hizo clic!');
}
window.onload=hacerclic;
En el Listado 4-6, en lugar de seleccionar solo el primer elemento encontrado, registramos el manejador de eventos onclick para cada uno de ellos usando un bucle for. Ahora, todos los elementos < p > dentro de < div > mostrarán una pequeña ventana cuando el usuario haga clic sobre ellos.
El método querySelectorAll(), al igual que querySelector(), puede contener uno o más grupos de selectores separados por coma. Estos y los demás métodos estudiados pueden combinarse para referenciar elementos a los que resulte difícil llegar. Por ejemplo, en el próximo listado, el mismo resultado del código del Listado 4-6 se alcanza utilizando querySelectorAll() y getElementById() juntos:
function hacerclic(){
var lista=document.getElementById(‘principal’).
querySelectorAll(“p”);
lista[0].onclick=mostraralerta;
}
function mostraralerta(){
alert('hizo clic!');
}
window.onload=hacerclic;
Usando esta técnica podemos ver qué precisos pueden ser estos métodos. Podemos combinarlos en una misma línea y luego realizar una segunda selección con otro método para alcanzar elementos dentro de los primeros. En próximos capítulos estudiaremos algunos ejemplos más.
Manejadores de eventos
Como comentamos anteriormente, el código Javascript se ejecuta normalmente luego de que el usuario realice alguna acción. Estas acciones y otros eventos se procesan por manejadores de eventos y funciones Javascript que se asocian con ellos.
Existen tres diferentes formas de registrar un evento para un elemento HTML: podemos agregar un nuevo atributo al elemento, registrar un manejador de evento como una propiedad del elemento o usar el nuevo método estándar addEventListener().
Conceptos básicos:
En Javascript, las acciones de los usuarios se llaman “eventos”. Cuando el usuario realiza una acción, como un clic del ratón o la presión de una tecla, un evento específico para cada acción y cada elemento es disparado. Además de los eventos que se produjeron a causa de los usuarios, existen también otros eventos que se disparan por el sistema (por ejemplo, el evento load que se dispara cuando el documento se carga completamente).
Estos eventos se manejan por códigos o funciones. El código que responde al evento ses llama manejador. Cuando registramos un manejador lo que hacemos es definir cómo nuestra aplicación responderá a un evento en particular. Luego de la estandarización del método addEventListener(), a este procedimiento usualmentse le llama“escuchar al evento”, y lo que hacemos para preparar el código que responderá a ese evento es “agregar una escucha” a un elemento en particular.
Manejadores de eventos en línea
Ya utilizamos esta técnica en el código del Listado 4-1 incluyendo el atributo onclick en el elemento < p > (revise este código para comprobar cómo se aplica). Se trata simplemente de utilizar los atributos provistos por HTML para registrar eventos para un elemento en particular. Esta es una técnica en desuso pero aun extremadamente útil y práctica en algunas circunstancias, especialmente cuando necesitamos hacer modificaciones rápidas para testeo.
Manejadores de eventos como propiedades
Para evitar las complicaciones de la técnica en línea (inline), debemos registrar los eventos desde el código Javascript. Usando selectores Javascript podemos referenciar el elemento HTML y asignarle el manejador de eventos que queremos como si fuese una propiedad.
En el código del Listado 4-2 encontrará esta técnica puesta en práctica. Dos manejadores de eventos se asignaron como propiedades a diferentes elementos. El manejador de eventos onload fue registrado para la ventana usando la construcción window.onload, y el manejador de eventos onclick fue registrado para el primer elemento encontrado en el documento con la línea de código document.getElementsByTagName(‘p’)[0].onclick.
Conceptos Básicos:
Los nombres de los manejadores de eventos son construidos agregando el prefijo on al nombre del evento. Por ejemplo, el nombre del manejador de eventos para el evento click es onclick. Cuando estamos hablando sobre onclick usualmente hacemos referencia al código que se ejecutará cuando el evento click se produzca.
Antes de HTML5, esta era la única técnica disponible para usar manejadores de eventos desde Javascript que funcionaba en todos los navegadores. Algunos fabricantes de navegadores estaban desarrollando sus propios sistemas, pero nada se adoptó por todos hasta que el nuevo estándar se declaró finalmente. Por este motivo recomendamos utilizar esta técnica por razones de compatibilidad, pero no la sugerimos para sus aplicaciones HTML5.
El método addEventListener()
El método addEventListener() es la técnica ideal y la que se considera como estándar por la especificación de HTML5. Este método tiene tres argumentos:
- El nombre del evento
- La función a ejecutar
- Un valor booleano (falso o verdadero). Este indica cómo un evento se disparará en elementos superpuestos.
<!DOCTYPE html>
<html lang="es">
<head>
<title>Este texto es el título del documento</title>
<script>
function mostraralerta(){
alert('hizo clic!');
}
function hacerclic(){
var elemento=document.getElementsByTagName('p')[0];
elemento.addEventListener(‘click’, mostraralerta, false);
}
window.addEventListener(‘load’, hacerclic, false);
</script>
</head>
<body>
<div id=”principal”>
<p>Hacer Clic</p>
<p>No puede hacer Clic</p>
</div>
</body>
</html>
El Listado 4-8 presenta el mismo código que el Listado 4-2 pero ahora una escucha se agregó para cada evento usando el método addEventListener(). Para organizar el código en la función hacerclic(), asignamos la referencia al elemento a una variable llamada elemento y luego agregamos la escucha para el evento click usando esa variable.
La sintaxis del método addEventListener() es la mostrada en el Listado 4-8. El primer atributo es el nombre del evento. El segundo es la función a ejecutar, la cual puede ser una referencia a una función (como en este caso) o una función anónima. El tercer atributo especificará, usando true (verdadero) o false (falso), cómo múltiples eventos serán disparados.
Ejemplificación
Por ejemplo, si estamos escuchando al evento click en dos elementos que se encuentran anidados (uno dentro de otro), cuando el usuario hace clic sobre estos elementos dos eventos click son disparados en un orden que depende de este valor. Si el atributo se declara como true para uno de los elementos, entonces ese evento se considerará primero y el otro luego. Normalmente, el valor false es el más adecuado para la mayoría de las situaciones.
Incluso cuando los resultados de aplicar esta técnica y la anterior son similares, addEventListener() nos permite agregar tantas escuchas como necesitemos para el mismo elemento. Esta distinción le otorga a addEventListener() una ventaja sobre el resto, convirtiéndola en la técnica ideal para aplicaciones HTML5.
Debido a que los eventos son la clave para sitios webs y aplicaciones interactivas, varios se agregaron en la especificación de HTML5. En próximos capítulos estudiaremos cada uno de estos nuevos eventos y el entorno en el cual trabajan.
APIs
Si cuenta con alguna experiencia anterior en programación, o simplemente siguió este capítulo desde el comienzo, le resultará fácil reconocer la cantidad de código necesario para realizar tareas sencillas. Ahora imagine todo el trabajo que debería hacer para construir un sistema de bases de datos desde cero, o generar gráficos complejos en la pantalla, o crear una aplicación para manipulación de imágenes, por nombrar unos pocos.
Javascript es tan poderoso como cualquier otro lenguaje de desarrollo en este momento. Y por la misma razón que lenguajes de programación profesionales poseen librerías para crear elementos gráficos, motores 3D para video juegos o interfaces para acceder a bases de datos, Javascript cuenta con APIs para ayudar a los programadores a lidiar con actividades complejas.
HTML5 introduce varias APIs (interfaces de programación de aplicaciones) para proveer acceso a poderosas librerías desde simple código Javascript. El potencial de estas incorporaciones es tan importante que pronto se convertirán en nuestro objeto de estudio. Veamos rápidamente sus características para obtener una perspectiva de lo que nos encontraremos en el resto del libro.
La siguiente es solo una introducción, más adelante estudiaremos cada una de estas tecnologías con mayor profundidad.