En el desarrollo de aplicaciones web modernas, a menudo necesitamos crear componentes con estructuras DOM más complejas que un simple elemento. Por ejemplo, imaginemos que queremos mostrar un mensaje de error con un diseño específico: un título, un texto explicativo, un icono y uno o varios botones para acciones como intentar otra vez. Si intentamos construir este componente manualmente con JavaScript usando createElement y appendChild, rápidamente nos encontraremos con un código difícil de mantener y poco eficiente.
Para abordar este problema, HTML5 nos ofrece una solución muy práctica: la etiqueta <template>. Esta etiqueta nos permite definir fragmentos de DOM que no se renderizan directamente en la página, sino que actúan como plantillas reutilizables. El contenido dentro de <template> pertenece a un árbol DOM independiente, lo que significa que no forma parte del DOM principal hasta que lo clonamos e insertamos explícitamente.
Para usar un template, primero lo definimos en nuestro HTML con un identificador, por ejemplo:
<template id="notificacion">
<div class="error">
<img src="icono-error.svg" alt="Error">
<h2>Error de guardado</h2>
<p>Tenemos problemas para comunicarnos con los servidores.</p>
<button>Intentar otra vez</button>
</div>
</template>
Este fragmento no se muestra en la página hasta que lo importamos y lo añadimos al DOM. Para acceder a su contenido desde JavaScript, usamos la propiedad content del elemento template, que nos devuelve un DocumentFragment con el contenido interno.
Sin embargo, dado que este fragmento pertenece a un documento DOM distinto, no podemos simplemente moverlo al DOM principal. Para transferirlo correctamente, utilizamos la función document.importNode, que clona el contenido del template y lo prepara para ser insertado. Es importante pasar true como segundo parámetro para que la clonación sea profunda, es decir, que incluya todos los nodos hijos y nietos.
Un ejemplo de cómo hacerlo sería:
const template = document.getElementById('notificacion');
const target = document.getElementById('target'); // Donde queremos insertar el mensaje
// Clonamos el contenido del template de forma profunda
const clone = document.importNode(template.content, true);
// Insertamos el clon en el DOM principal
target.appendChild(clone);
Con este método, podemos reutilizar la misma plantilla tantas veces como queramos, evitando la necesidad de crear manualmente cada elemento con JavaScript. Esto es especialmente útil cuando manejamos componentes con estructuras complejas o cuando queremos generar listas dinámicas, como filas de tablas o elementos en una lista de contactos.
Además, el uso de templates mejora la organización del código y la eficiencia al manipular el DOM, ya que trabajar con DocumentFragment es más rápido que insertar elementos uno a uno directamente en el DOM visible.
Cabe destacar que la etiqueta <template> está soportada en la mayoría de navegadores modernos, como Chrome, Firefox y Edge, pero no en Internet Explorer. En este último, la etiqueta se trataría como un elemento normal, por lo que habría que aplicar estilos CSS para ocultarla si se quiere evitar que se muestre.
En resumen, la etiqueta <template> es una herramienta muy valiosa para crear fragmentos DOM reutilizables y manejar componentes más elaborados sin complicarnos con múltiples llamadas a createElement y appendChild. Su uso combinado con document.importNode nos permite clonar y añadir estos fragmentos al DOM principal de forma sencilla y eficiente. Esto nos abre muchas posibilidades para construir interfaces web más limpias y mantenibles, especialmente cuando no queremos depender de frameworks externos.