Etiquetas HTML de scripts

A medida que aprendemos HTML vemos que se trata de un lenguaje de marcas estupendo y muy potente, pero también nos vamos dando cuenta que ciertos detalles no se pueden cubrir sólo con HTML y CSS. Para ello tenemos que hacer uso de un lenguaje de programación llamado Javascript.

Este lenguaje es muy potente y flexible, pero también requiere mayor dominio del código que con HTML y CSS, puesto que estos últimos sólo son lenguajes de marcas y estilos respectivamente, mientras que Javascript es un lenguaje de programación que requiere ciertos conocimientos y metodología de desarrollo.

En este artículo cubriremos una parte básica de Javascript muy relacionada con HTML. Si quieres aprender Javascript en profundidad, echa un ojo a LenguajeJS.com.

La etiqueta script

Para utilizar Javascript, lo que hacemos normalmente es indicar al HTML que queremos cargar un script (generalmente, un archivo de texto con código Javascript) y hacerlo funcionar sobre la página actual. Para hacer esto, utilizaremos la etiqueta <script>, que permite indicar una serie de atributos:

Atributo Valor Descripción
src URL Dirección URL del script externo a cargar.
type tipo Tipo de script a cargar. Si se omite, se asume text/javascript como valor.
nomodule Si se define este atributo, el script no se carga en navegadores modernos.
async Ejecuta el script cuando se haya descargado, sin bloquear el navegador.
defer Aplaza la ejecución del script, lo ejecuta al final, cuando haya descargado todo.

Para empezar, ten en cuenta que la etiqueta <script> tiene fundamentalmente dos modos de funcionar, que se basan en como definas la etiqueta <script>:

  • Como script en línea: El código JS se incluye en el HTML, dentro de la etiqueta.
  • Como script externo: El código JS se incluye en el fichero Javascript enlazado en src.

Un ejemplo de script en línea sería el siguiente. Observa que el código se incluye en el interior de la etiqueta, por lo que permanece en el documento HTML:

<script>
  alert('¡Hola!');
</script>

El siguiente código, por otro lado, es un script externo, donde el código Javascript se encuentra en un archivo separado del HTML, concretamente en la ruta /js/script.js:

<script src="/js/script.js"></script>

En ambos casos, el navegador interrumpirá la carga de la página para procesar y ejecutar el Javascript, detalle que quizás no sea el más adecuado para nuestro desarrollo. Veremos como se puede modificar en el siguiente apartado.

Modo de carga del script

Cuando indicamos un script externo mediante el atributo src, por defecto el proceso de carga del script por parte del navegador es el siguiente:

  • Detiene temporalmente la carga del HTML en el lugar donde se encontró el <script>.
  • Descarga el script .js al caché de ficheros temporales del navegador.
  • Ejecuta el script una vez descargado.
  • Reanuda la carga del documento HTML por donde lo dejó, en cuanto termina la ejecución del script.

Este es el modo de carga por defecto de los scripts por parte del navegador. Sin embargo, existen dos métodos de carga diferentes: la carga asíncrona y la carga diferida:

Modo de carga Atributo Descripción
Carga normal (ninguno) Bloquea la carga de la página y se ejecuta inmediatamente.
Carga asíncrona async Ejecuta el script tan pronto como esté disponible.
Carga diferida defer Aplaza la ejecución del script al final de la carga de la página.

Estos dos métodos tienen ligeras diferencias respecto al modo de carga básico que vimos anteriormente, y que aparece el primero en la siguiente ilustración:

Modo de carga de scripts

  • Carga asíncrona: El navegador descarga el script sin detener la carga del documento HTML. Una vez descargado, detiene la carga del documento HTML temporalmente, ejecuta el script, y una vez terminada la ejecución, continua con la carga del documento HTML. Este tipo de carga se realiza incluyendo el atributo async en la etiqueta <script>.

  • Carga diferida: El navegador le da prioridad a la carga del documento HTML. Descarga el script de forma paralela sin detener la carga del documento HTML. Una vez ha terminado de cargar el documento HTML, ejecuta el script. Este tipo de carga se realiza incluyendo el atributo defer en la etiqueta <script>.

Carga de módulos Javascript

En los últimos años, Javascript ha incluido una funcionalidad llamada módulos de Javascript. Dichos módulos son una modalidad específica de archivos Javascript, los cuales pueden compartir funcionalidades a través de las palabras clave import y export.

Estas funcionalidades están prohibidas por defecto, y sólo se podrán realizar si a la hora de cargar el script con la etiqueta <script> definimos el atributo type a module. Esto nos permitirá cargar el archivo Javascript como módulo y utilizarlo:

<script type="module">
  import { Howler, Howl } from "https://unpkg.com/howler";
</script>

Es posible usar el atributo type="module" tanto en etiquetas <script> en línea (ejemplo anterior) como con etiquetas <script> que utilicen el atributo src. Además, todos los scripts cargados como módulos, se ejecutarán en modo diferido.

En algunos casos, podemos crear etiquetas <script> que utilicen un atributo nomodule. Dicho atributo indicará a navegadores modernos que soportan el atributo type=module, que no deben descargar ni ejecutar ese script. Sin embargo, navegadores antiguos que no lo soportan cargarán el script como un fichero Javascript normal y corriente:

<script type="module">
  /* Código para navegadores modernos */
  import { Howler, Howl } from "https://unpkg.com/howler";
</script>
<script nomodule>
  /* Código para navegadores antiguos */
</script>

La finalidad de este atributo es poder crear scripts a modo de fallback para realizar tareas equivalentes en navegadores antiguos y dar soporte a otros sistemas menos modernos. Es lo que se conoce como el patrón module/nomodule.

Lenguajes de scripting

Por defecto, el lenguaje de scripting soportado por los navegadores es Javascript, por lo que cuando hablamos de scripting en el navegador (front-end, o en el lado del cliente) hablamos de este lenguaje. Javascript está basado en ECMAScript, el estándar que indica como debe actuar el lenguaje. Luego, es misión de cada navegador implementarlo de acuerdo a esas normas, aunque siempre hay algunas diferencias entre navegadores.

Existen alternativas para no utilizar Javascript directamente, sino algún lenguaje similar que traduce (o mejor dicho, transpila) a Javascript. Directamente, los navegadores solo soportan Javascript. Quizás, los transpiladores más populares a Javascript sean TypeScript y Babel.

La etiqueta noscript

Debemos ser conscientes de que, aunque actualmente la mayoría de los navegadores poseen Javascript, un usuario puede acceder desde un dispositivo que no tenga Javascript (muy poco habitual) o que tenga Javascript deshabilitado (poco habitual). Una buena costumbre, es proporcionar una alternativa (aunque sea mínima) para aquellos usuarios que no tengan Javascript habilitado.

Para ello, utilizaremos la etiqueta <noscript>:

<script>
  var usuario = prompt("¿Cuál es tu nombre?");
  alert("¡Hola, " + usuario + "!");
</script>
<noscript>
  ¡Hola, usuario!
</noscript>

En caso de que el usuario tenga capacidades de Javascript en su navegador, se ejecutará el código de la etiqueta <script>, sin embargo, si el navegador no tiene Javascript, se mostrará el texto proporcionado en la etiqueta <noscript>, que aunque no puede recoger el nombre de usuario, mostrará una alternativa.

De esta forma evitamos que si el usuario no tiene Javascript, vea una página en blanco.

La etiqueta template

La etiqueta <template> es un método ideal para reutilizar información HTML y tratarla mediante Javascript. En el siguiente ejemplo tenemos una tabla HTML que sólo tiene definida la cabecera de la misma. Sin embargo, un poco más abajo hay una etiqueta <template> que contiene una fila con 3 celdas:

<table id="tabla">
  <tr>
    <th>Nombre</th>
    <th>Apellidos</th>
    <th>Calificación</th>
  </tr>
  <template id="usuario">
    <tr>
      <td>1</td>
      <td>2</td>
      <td>3</td>
    </tr>
  </template>
</table>

El contenido de una etiqueta <template> es inerte, de modo que el navegador no interpreta su interior (no descarga imágenes, no ejecuta scripts, etc...) hasta que el usuario clona su contenido para insertarlo en el HTML.

En este ejemplo anterior, nosotros podríamos desde Javascript obtener el contenido de la plantilla <template>, clonarlo y añadirlo al final de la tabla de forma dinámica, para posteriormente modificar los datos de cada fila:

var template = document.getElementById("usuario");
var tabla = document.getElementById("tabla");

tabla.appendChild(template.content.cloneNode(true));

Si te interesa este tema, tienes más información sobre la etiqueta <template> (y plantillas en general) en este artículo sobre Plantillas, DOM y WebComponents.

Las plantillas HTML tienen relativamente buen soporte, aunque en el caso de querer dar soporte a Internet Explorer habría que utilizar algún polyfill como Minimal Polyfill for Template:

Manz
Publicado por Manz

Docente, divulgador informático y freelance. Autor de Emezeta.com, es profesor en la Universidad de La Laguna y dirige el curso de Programación web FullStack y Diseño web FrontEnd de EOI en Tenerife (Canarias). En sus ratos libres, busca GIF de gatos en Internet.