009. Creando Elementos y Fragmentos

En este capítulo vamos a ver como crear elementos (etiquetas HTML) dinámicamente a través de Javascript. Hasta ahora hemos aprendido a manipular las etiquetas existentes en nuestros archivos HTML, en este capítulo vamos a comenzar a crear nuestras propias etiquetas dinámicas.

Crear nodos uno por uno

El DOM tiene un método denominado createElement(), que como su nombre indica, va a crear un elemento del DOM. En nuestro ejm vamos a crear una etiqueta <figure> con la siguiente sintaxis.

// Crear 3 nuevas etiquetas
const $figure = document.createElement("figure"),
$img = document.createElement("img"),
$figcaption = document.createElement("figcaption");

// Crear nuevos nodos de texto
$figcaptionText = document.createTextNode("City");

Después de crear las 3 etiquetas nuevas que se unirán a las tarjetas que están creadas en nuestro ejm, tenemos que configurar los atributos de las mismas.

Posteriormente a ello vamos a capturar el elemento padre donde vamos a incluir la nueva tarjeta. La sintaxis es.

$cards = document.querySelector(".cards");

Dinámicamente, hasta ahora hemos creado ya las etiquetas, lo único, no están incorporadas aún al árbol del DOM. Para ello debemos irlas agregando.

El siguiente paso es agregar las etiquetas al árbol del DOM, para ello tenemos un método llamado appendChild() (agregar un hijo en inglés) donde especificamos el nodo que queremos agregar.

// Agregar atributos a $img
$img.setAttribute("src","city.jpg");

// Agregamoa a $figcaption (elemento padre) $figcaptiontext
$figcaption.appendChild($figcaptionText);

// Agregamos a $figure (elemento padre) $img y $figcaption
$figure.appendChild($img);
$figure.appendChild($figcaption);

// Agregamos a $cards (elemento padre) $figure
$cards.appendChild($figure);

Ejm completo

Ejm

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Creando elementos dinámicamente</title>
<style>
:root {
--yellow-color: #f7df1e;
--dark-color: #222;
}

.cards {
border: thin solid var(--dark-color);
padding: 1rem;
}

.card {
display: inline-block;
background-color: var(--dark-color);
color: var(--yellow-color)
}

.card figcaption {
padding: 1rem;
}

.rotate-45 {
transform: rotate(45deg);
}

img {
width: 20px;
height: 300px;
}
</style>
</head>
<body>
<h1>Creando elementos dinámicamente</h1>
<section class="cards">
<figure class="card">
<img src="tech.jpg" alt="Tech">
<figcaption>Tech</figcaption>
</figure>
<figure class="card">
<img src="animals.avif" alt="Animals">
<figcaption>Animals</figcaption>
</figure>
<figure class="card">
<img src="people.avif" alt="People">
<figcaption>People</figcaption>
</figure>
<figure class="card">
<img src="arch.webp" alt="Arch">
<figcaption>Arch</figcaption>
</figure>
<figure class="card">
<img src="nature.jpg" alt="Nature">
<figcaption>Nature</figcaption>
</figure>
</section>

<script>
// Crear elementos
const $figure = document.createElement("figure"),
$img = document.createElement("img"),
$figcaption = document.createElement("figcaption");

// Crear nodo de texto para figcaption
$figcaptionText = document.createTextNode("City");

// Capturar el elemento padre donde se incluirá el contenido nuevo
$cards = document.querySelector(".cards");

// Agregar atributos a $img
$img.setAttribute("src","city.jpg");
$img.setAttribute("alt","City");

// Añadimos la clase card
$figure.classList.add("card");

// Agregar etiquetas al árbol del DOM
$figcaption.appendChild($figcaptionText);
$figure.appendChild($img);
$figure.appendChild($figcaption);
$cards.appendChild($figure);
</script>
</body>
</html>

Nota: los pasos a seguir son: primero creamos el nuevo elemento con createElement(), después le damos valor si hemos de dárselo con textContent en el caso de que sea texto plano, después le agregamos los atributos mediante setAttribute(), después le agregamos las clases mediante classList.add(), y por último al elemento padre le agregamos los nuevos elementos hijos mediante el método appenChild().

Otro ejm

Veamos otro ejm para familiarizarnos con el uso

Ejm

const estaciones = ["Primavera", "Verano", "Otoño", "Invierno"];

$ul = document.createElement("ul");

document.write("<h3>Estaciones del año</h3>");

// Agregamos al body (nodo padre) la etiqueta <ul>
document.body.appendChild($ul);

estaciones.forEach(el=> {
  // Creamos las etiquetas <li>
  const $li = document.createElement("li");

  // Añadimos texto a cada etiqueta <li>
  $li.textContent = el;

  // Agregamos al elemento padre ($ul) el elemento
  // hijo ($li)
  $ul.appendChild($li);
});

Otro ejm usando template strings

Veamoslo con un ejm

const dias = ["lunes","martes"],
$ul = document.createElement("ul");

document.write("Dias de la semana");
document.body.appenChild($ul);

// Utilizamos innerHTML (ojo, no estamos creando un nodo)
// Inicializamos la propiedad innerHTML con un valor nulo
$ul.innerHTML = "";
dias.forEach(el => $ul.innerHTML += <li>${el}</li>;

Renderizar varios elementos, crear fragmentos dinámicos

En el DOM podemos crear fragmentos dinámicos, que son como una variable que se crea dinámicamente, y a ese fragmento del DOM le podemos estar iterando, de tal manera que en vez de estar iterando directamente al DOM, se lo iteramos a dicho fragmento del DOM, el cual está en memoria, no directamente en el DOM, y una vez tengamos todos los elementos cargados en ese fragmento, hacemos una sola y única inserción al DOM, con todos los registros que nuestra petición haya capturado, lo que mejora el rendimiento de nuestra página web. Hagamos un ejm para entenderlo.

Ejm

const meses = ["Enero", "Febrero"],
$ul = document.createElement("ul"),
$fragment = document.createDocumentFragment();

meses.forEach(el => {
  const $li = document.createElement("li");
  $li.textContent = el;

  // Le agregamos al nodo fragmento un appenChild()
  $fragment.appendChild($li);
});

document.write("<h3>Meses del año</h3>");
$ul.appendChild($fragment);
document.body.appendChild($ul);

De esta manera hacemos una sóla inserción al DOM, y funciona perfectamente. Es una manera más óptima para no pedirle tanta demanda de recursos al navegador del usuario que está interactuando con nuestra aplicación.

Nota: desde ahora hay que irse acostumbrando a utilizar fragmentos en vez de insertar directamente nodos al DOM.

Resumen

Los métodos que hemos visto en este capítulo son:

  • createElement(“etiqueta”): crea un nuevo elemento.
  • createTextNode(“texto”): crea un nuevo nodo de texto.
  • appenChild(): agrega elementos al árbol del DOM.
  • createDocumentFragment(): crea un fragmento.
Scroll al inicio