El árbol DOM puede cambiar después de que el navegador lo haya renderizado. Este hecho permite crear aplicaciones interactivas.
En esta lección discutiremos cómo manipular árboles DOM y qué ventajas podemos obtener al hacerlo.
innerHTML
La forma más sencilla de actualizar una parte del DOM es a través de la propiedad innerHTML:
<ul>
<li>elemento 1</li>
<li>elemento 2</li>
</ul>
const body = document.body;
console.log(body);
// <ul><li>elemento 1</li><li>elemento 2</li></ul>
body.innerHTML = '<b>make</b> love';
console.log(body.innerHTML);
// <b>make</b> love
console.log(body.childNodes);
// [b, text]
El valor de esta propiedad reemplaza completamente a los nodos descendientes del elemento en el que se llama. Todo el HTML dentro de él se analiza y se convierte en parte del árbol.
Imaginemos que intentamos insertar un texto normal que potencialmente contiene HTML. Esto aumenta la probabilidad de ataques XSS (Cross-site scripting (XSS) es una vulnerabilidad de seguridad que permite a un atacante inyectar en un sitio web código malicioso del lado del cliente). Para prevenir esto, debemos usar otra propiedad textContent.
La propiedad textContent funciona de manera casi idéntica, también reemplaza a todos los nodos descendientes. La principal diferencia entre estas propiedades es que textContent considera el contenido como texto normal en cualquier caso, incluso si hay HTML:
document.body.textContent = '<b>make</b> love';
console.log(document.body.innerHTML);
// Todos los caracteres especiales se reemplazan
// "<b>make</b> love"
La propiedad innerHTML trabaja con cadenas de texto. Esto es conveniente solo si estamos trabajando con una representación estática del DOM. Para la construcción dinámica, son más adecuadas las funciones especiales.
Creación de nodos
// Creamos un nodo de texto
const textNode = document.createTextNode('life is life');
// Creamos un elemento p
const pEl = document.createElement('p');
// Agregamos textNode al final de la lista de childNodes de pEl
pEl.append(textNode);
// pEl.textContent = 'life is life';
const el = document.createElement('div');
el.append(pEl);
console.log(el);
// <div><p>life is life</p></div>
El código que crea el DOM dinámicamente se parece a una muñeca rusa. Después de crear un elemento, se anidan constantemente dentro de otros. Así es como se ve el código que construye árboles en cualquier lenguaje.
Inserción
ParentNode.prepend() / MDN Web Docs (inglés) agrega el nodo pasado como primer nodo descendiente al ParentNode:
const div = document.createElement('div');
div.innerHTML = '<span>Códica</span>';
const el = document.createElement('p');
el.textContent = 'prepend';
div.prepend(el);
// <div>
// <p>prepend</p>
// <span>Códica</span>
// </div>
ParentNode.append() / MDN Web Docs (español) agrega el nodo pasado como último nodo descendiente al ParentNode:
const div = document.createElement('div');
div.innerHTML = '<span>Códica</span>';
const el = document.createElement('p');
el.textContent = 'append';
div.append(el);
// <div>
// <span>Códica</span>
// <p>append</p>
// </div>
childNode.before(...nodes) / MDN Web Docs (inglés) inserta nodes en la lista de nodos descendientes del nodo padre childNode justo antes de childNode:
const div = document.createElement('div');
div.innerHTML = '<span>Códica</span>';
// Debe ser insertado en el árbol DOM
document.body.append(div);
const el = document.createElement('p');
el.textContent = 'contenido';
div.before(el);
// <p>contenido</p>
// <div>
// <span>Códica</span>
// </div>
childNode.after(...nodes) / MDN Web Docs (inglés) inserta nodes en la lista de nodos descendientes del nodo padre childNode justo después de childNode:
const div = document.createElement('div');
div.innerHTML = '<span>Códica</span>';
// Debe ser insertado en el árbol DOM
document.body.append(div);
const el = document.createElement('p');
el.textContent = 'contenido';
div.after(el);
// <div>
// <span>Códica</span>
// </div>
// <p>contenido</p>
node.replaceWith(...nodes) / MDN Web Docs (inglés) reemplaza node con nodes. El propio node desaparece del árbol DOM, pero sigue siendo accesible en el código:
const div = document.createElement('div');
div.innerHTML = '<span>Códica</span>';
// Debe ser insertado en el árbol DOM
document.body.append(div);
const el = document.createElement('p');
el.textContent = 'contenido';
div.replaceWith(el);
// En el árbol DOM, en lugar de div, queda p
// <p>contenido</p>
Element.remove() / MDN Web Docs (español) elimina el nodo actual.
API antiguo
Las funciones descritas anteriormente son relativamente nuevas. La mayor parte del código se ha escrito utilizando otras funciones, que se enumeran a continuación:
parent.appendChild(el)- agregaelal final de la lista de nodos descendientes.parent.insertBefore(el, nextElSibling)- agregaela la lista de nodos descendientes deparentantes denextElSibling.parent.removeChild(el)- eliminaelde los nodos descendientes deparent.parent.replaceChild(newEl, el)- reemplazaelconnewEl.
Clonación
A veces necesitamos crear un elemento similar a uno existente. Por supuesto, esto se puede hacer manualmente copiando las propiedades de un elemento a otro. Pero hay una forma más sencilla:
const newEl = el.cloneNode(true);
El valor true indica que estamos creando una copia profunda, es decir, una copia del elemento y todos sus nodos descendientes.
Para acceder completo a curso necesitas un plan básico
El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.