Insertar elementos en el DOM

Formas de añadir elementos en una página


En capítulos anteriores hemos visto formas de crear elementos en el DOM e incluso modificar el contenido de elementos HTML. Aunque mediante propiedades como .innerHTML podemos insertar elementos en el DOM de un documento HTML, en muchas ocasiones quizás no es la mejor forma.

Si tenemos que hacer múltiples inserciones o necesitamos insertar elementos manteniendo intacta la estructura existente (o los listeners de eventos asociados), estaría bien disponer de formas en las que podamos indicar exactamente donde queremos añadir el elemento, de forma más controlada. Y eso es lo que vamos a ver en este artículo.

Veamos 3 formas (de más tradicional a más moderna) de inserción o modificación de elementos:

  • 1️⃣ La API de nodos
  • 2️⃣ La API de elementos
  • 3️⃣ La API de inserción adyacente

Puedes usar la que prefieras, que se adapte mejor a tus necesidades.

API de nodos

La API de nodos de Javascript es la más tradicional y antigua, y aunque cumple bien determinados aspectos, suele ser más complicado llegar al objetivo porque no hay ciertos métodos explícitos para hacer determinadas cosas. No obstante, suele ser la más extendida que te encuentras, ya que .appendChild() está muy extendido al ser uno de los más usados:

Métodos Descripción
.appendChild(node) Añade como hijo el nodo node. Devuelve el nodo insertado.
.removeChild(node) Elimina y devuelve el nodo hijo node.
.replaceChild(new, old) Reemplaza el nodo hijo old por new. Devuelve old.
.insertBefore(new, node) Inserta el nodo new antes de node y como hijo del nodo actual.
.insertBefore(new, ) Inserta el nodo new después del último nodo hijo. Equivale a .appendChild().

De ellos, probablemente el método más extendido y conocido es .appendChild(). Vamos a analizar cada uno de ellos y ver como podemos utilizarlos.

El método .appendChild()

Uno de los métodos más comunes para añadir un elemento HTML creado con Javascript es .appendChild(). Como su propio nombre indica, este método añade o inserta un nuevo elemento, como si fuera un hijo al final de todos los hijos del elemento sobre el que se realiza.

createElement

Es importante tener claro donde se inserta, porque aunque es bastante común, no siempre querremos insertar el elemento en esa posición particular.

Observa el siguiente fragmento de código:

const container = document.querySelector(".container");

const img = document.createElement("img");
img.src = "https://lenguajejs.com/assets/logo.svg";
img.alt = "Logo Javascript";

container.appendChild(img);

En este ejemplo, creamos un elemento <img> que aún no está conectado al DOM de la página. Existe sólo en la constante <img>. Posteriormente, añadimos los atributos src y alt y lo conectamos al DOM el elemento usando el método .appendChild().

Se insertará como último hijo del elemento <body>, ya que es su comportamiento predefinido.

El método .removeChild()

En algunos casos, nos puede interesar eliminar un nodo hijo de un elemento. Para esas situaciones, podemos utilizar el método .removeChild(node) donde node es el nodo hijo que queremos eliminar:

const container = document.querySelector(".container");
const secondItem = container.querySelector(".item:nth-child(2)");

container.removeChild(secondItem); // Desconecta el segundo .item

El método .replaceChild()

De la misma forma, el método replaceChild(new, old) nos permite cambiar un nodo hijo old por un nuevo nodo hijo new. En ambos casos, el método nos devuelve el nodo reemplazado:

const container = document.querySelector(".container");
const secondItem = container.querySelector(".item:nth-child(2)");

const newNode = document.createElement("div");
newNode.textContent = "DOS";

container.replaceChild(newNode, secondItem);

El método .insertBefore()

Por último, el método insertBefore(newnode, node) es un método más específico y menos utilizado en el que se puede especificar exactamente el lugar a insertar un nodo. El primer parámetro es el nodo a insertar, mientras que el segundo parámetro puede ser:

  • ► inserta newnode después del último nodo hijo. Equivale a .appendChild().
  • ► inserta newnode antes de dicho node de referencia.
const container = document.querySelector(".container");
const secondItem = container.querySelector(".item:nth-child(2)");

const newNode = document.createElement("div");
newNode.textContent = "Nuevo elemento";

container.insertBefore(newNode, secondItem);

En este caso, el nuevo elemento aparecería justo antes del segundo item.


API de elementos

Los métodos mencionados con anterioridad sirven en muchos casos, sin embargo, son poco específicos y puede que no cubran todas las posibles situaciones. Existe otra familia de métodos para añadir e insertar elementos que quizás sea mucho más versátil.

Todos los métodos permiten pasar por parámetro un elemento o una lista de elementos. También puedes pasar un (para insertar un fragmento de texto). Echemos un vistazo a estos métodos:

Métodos Descripción
.before() Añade el nuevo elemento justo antes.
.after() Añade el nuevo elemento justo después.
.prepend() Se añade el nuevo elemento antes del primer hijo.
.append() Se añade el nuevo elemento después del último hijo.
.replaceChildren() Elimina todos los hijos y los sustituye por el nuevo elemento.
.replaceWith() Se sustituye por el nuevo elemento.
.remove() Elimina el propio elemento.

Vamos a suponer que estos métodos los vamos a ejecutar en base al elemento container, por lo que todo se hará respecto a él. Por ejemplo, container.before().

El método .before() y .after()

Con el método .before() podemos insertar uno o varios elementos antes del elemento que llama al before (en el ejemplo, container). Con el método .after() ocurre exactamente lo mismo, pero después del elemento en lugar de antes:

El método prepend, append, before y after

Veamoslo con un ejemplo:

const element = document.createElement("div");
element.textContent = "Item insertado";

// A) Inserta antes de .container
container.before(element);

// B) Inserta después de .container
container.after(element);

El método .prepend() y .append()

Con estos dos métodos podemos insertar elementos en sus elementos hijos, al principio o al final. El método .prepend() permite insertar uno o varios elementos antes del primer elemento hijo de nuestro elemento base. En el caso de append() ocurre lo mismo, pero después del último elemento hijo:

const element = document.createElement("div");
element.textContent = "Item insertado";

// A) Inserta antes del primer hijo de .container
container.prepend(element);

// B) Inserta después del último hijo de .container
container.append(element);

El método .append() es equivalente al .appendChild() que vimos más atrás.

El método .replaceChildren() y .replaceWith()

Por otro lado, también tenemos los métodos .replaceChildren() y .replaceWith(). El primero de ellos, replaceChildren() permite eliminar todos los elementos hijos del elemento base, y sustituirlos por uno o varios que indiques por parámetro.

El método replaceChildren y replaceWith

El segundo método, replaceWith(), lo que permite es reemplazar el propio elemento base con uno o varios elementos que pasemos por parámetro, por lo que se realiza un reemplazo completo:

const element = document.createElement("div");
element.textContent = "Nuevo Item hijo";

// A) Reemplaza por todos sus hijos
container.replaceChildren(element);

// B) El container es reemplazado por el nuevo item hijo
container.replaceWith(element);

El método .remove()

Al igual que podemos insertar o reemplazar elementos, también podemos eliminarlos. Ten en cuenta que al «eliminar» un nodo o elemento HTML, lo que hacemos realmente no es borrarlo, sino desconectarlo del DOM o documento HTML, de modo que no están conectados, pero siguen existiendo.

El método .remove() se encarga de desconectarse del DOM a sí mismo,

const div = document.querySelector(".deleteme");

div.isConnected;    // true
div.remove();
div.isConnected;    // false

En este caso, lo que hemos hecho es buscar el elemento HTML <div class="deleteme"> en el documento HTML y desconectarlo de su elemento padre, de forma que dicho elemento pasa a no pertenecer al documento HTML, pero sigue existiendo en la constante div.


API de inserción adyacente

Probablemente, una de las APIs de manejo del DOM más desconocidas y más interesantes, es la de Inserción de elementos adjacentes. Son una familia de 3 métodos que permiten hacer prácticamente cualquier operación posible en el DOM.

Son los métodos que tenemos a continuación:

Métodos Descripción
.insertAdjacentElement(position, element) Inserta el element en la posición position. Si falla, .
.insertAdjacentHTML(position, htmlCode) Inserta el código HTML de htmlCode en la posición position.
.insertAdjacentText(position, text) Inserta el texto text en la posición position.

Los métodos de la familia insertAdjacent son bastante más versátiles que .appendChild(), ya que permiten muchas más posibilidades. Tenemos tres versiones diferentes:

  • .insertAdjacentElement() donde insertamos una etiqueta HTML
  • .insertAdjacentHTML() donde insertamos código HTML directamente (similar a innerHTML)
  • .insertAdjacentText() donde insertamos un texto directamente (similar a textContent)

Ten en cuenta que position es un que puede tener uno de los siguientes valores:

beforebegin, afterbegin, beforeend, y afterend

Valor Descripción Equivalente a...
beforebegin Inserta el elemento antes de la etiqueta HTML de apertura. before()
afterbegin Inserta el elemento dentro, antes de su primer hijo. preprend()
beforeend Inserta el elemento dentro, justo antes de la etiqueta HTML de cierre. append() o appendChild()
afterend Inserta el elemento después de la etiqueta HTML de cierre. after()

Veamos algunos ejemplo aplicando cada uno de ellos con el método .insertAdjacentElement():

const container = document.querySelector(".container");

// Creamos un nuevo <div>Ejemplo</div>
const div = document.createElement("div");
div.textContent = "Ejemplo";

container.insertAdjacentElement("beforebegin", div);
// A) <div>Ejemplo</div> <div class="container">container</div>

container.insertAdjacentElement("afterbegin", div);
// B) <div class="container"> <div>Ejemplo</div> container</div>

container.insertAdjacentElement("beforeend", div);
// C) <div class="container">container <div>Ejemplo</div> </div>

container.insertAdjacentElement("afterend", div);
// D) <div class="container">App</div> <div>Ejemplo</div>

Ten en cuenta que en el ejemplo muestro varias opciones alternativas, no lo que ocurriría tras ejecutar las cuatro opciones una detrás de otra.

Por otro lado, notar que tenemos tres versiones en esta familia de métodos, una que actúa sobre elementos HTML (la que hemos visto), pero otras dos que actuan sobre código HTML y sobre nodos de texto. Veamos un ejemplo de cada una:

container.insertAdjacentElement("beforebegin", div);
// A) <div>Ejemplo</div> <div class="container">App</div>

container.insertAdjacentHTML("beforebegin", "<p>Hola</p>");
// B) <p>Hola</p> <div class="container">App</div>

container.insertAdjacentText("beforebegin", "Hola a todos");
// C) Hola a todos <div class="container">App</div>

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev