tutoriales.com

Manipulación del DOM con JavaScript: Interactividad Dinámica en tu Web

Este tutorial te guiará a través del poderoso mundo de la manipulación del Document Object Model (DOM) con JavaScript. Descubrirás cómo acceder, modificar y crear elementos HTML, estilos y atributos, dotando a tus páginas web de interactividad dinámica. Desde los conceptos básicos hasta técnicas avanzadas, te convertirás en un experto en hacer que tus sitios web cobren vida.

Intermedio20 min de lectura6 views
Reportar error

✨ Introducción a la Manipulación del DOM en JavaScript

El Document Object Model (DOM) es la interfaz de programación para documentos HTML y XML. Representa la página para que los programas puedan cambiar la estructura, el estilo y el contenido del documento. En el contexto de los navegadores web, el DOM es crucial porque JavaScript puede interactuar con él para hacer que las páginas web sean dinámicas e interactivas.

Piénsalo de esta manera: un documento HTML es como el esqueleto y la piel de tu página web, mientras que CSS es la ropa y el maquillaje que le dan estilo. JavaScript, al manipular el DOM, es el cerebro que le permite moverse, interactuar y responder a los usuarios. Sin la manipulación del DOM, las páginas web serían estáticas y aburridas.

En este tutorial, exploraremos a fondo cómo JavaScript puede acceder a los elementos HTML, modificar sus propiedades, añadir o eliminar contenido y responder a eventos del usuario. Prepárate para darle vida a tus proyectos web.

💡 Consejo: La manipulación del DOM es una habilidad fundamental para cualquier desarrollador web frontend. ¡Dominarla te abrirá un mundo de posibilidades!

📖 ¿Qué es el DOM? Una Visión Profunda

El DOM no es parte de JavaScript per se, pero es la API que JavaScript utiliza para interactuar con el HTML del navegador. Es una representación estructurada (un árbol de nodos) del documento HTML. Cada parte del documento, como elementos, atributos, texto, comentarios, etc., se convierte en un nodo en este árbol. Esto permite a JavaScript acceder y modificar cada uno de estos nodos.

La Estructura del Árbol DOM

Imagina tu documento HTML como un árbol genealógico. El document es la raíz de todo. Dentro de él, tienes el elemento <html>, que es el padre de <body> y <head>. A su vez, <body> tiene hijos como <h1>, <p>, <div>, etc. Cada uno de estos elementos puede tener sus propios hijos, y así sucesivamente.

DOCUMENT HTML HEAD BODY TITLE META H1 P DIV SPAN

Cada nodo en el árbol DOM es un objeto. Estos objetos tienen propiedades y métodos que JavaScript puede usar para interactuar con ellos. Por ejemplo, un nodo de elemento tendrá propiedades como id, className, innerHTML, y métodos como appendChild() o remove(). El objeto global document es la puerta de entrada a todo este árbol.


🔍 Seleccionando Elementos del DOM

Antes de poder manipular un elemento, primero debemos seleccionarlo. JavaScript ofrece varias formas de hacer esto. Elegir el método adecuado depende de si el elemento tiene un ID, una clase, una etiqueta o una combinación de atributos.

Métodos de Selección Clásicos

Estos son los métodos más antiguos y aún ampliamente utilizados:

  • document.getElementById('id-del-elemento'): Selecciona un elemento por su atributo id. Es el método más rápido porque los IDs son únicos en el documento.
  • document.getElementsByClassName('clase-del-elemento'): Devuelve una HTMLCollection (similar a un array) de todos los elementos que tienen una clase específica.
  • document.getElementsByTagName('nombre-de-etiqueta'): Devuelve una HTMLCollection de todos los elementos con un nombre de etiqueta específico (ej. div, p, a).
  • document.getElementsByName('nombre-de-atributo'): Devuelve una NodeList de todos los elementos con un atributo name específico (usado a menudo en formularios).
// HTML de ejemplo:
// <div id="miDiv" class="contenedor principal">Hola Mundo</div>
// <p class="texto-resaltado">Este es un párrafo.</p>
// <p class="texto-resaltado">Otro párrafo.</p>

const miDiv = document.getElementById('miDiv');
console.log(miDiv); // Muestra el elemento div

const parrafosResaltados = document.getElementsByClassName('texto-resaltado');
console.log(parrafosResaltados); // HTMLCollection de los dos párrafos
console.log(parrafosResaltados[0]); // El primer párrafo

const todosLosParrafos = document.getElementsByTagName('p');
console.log(todosLosParrafos); // HTMLCollection de todos los párrafos

// Para elementos de formulario:
// <input type="radio" name="opcion" value="a">
// const opciones = document.getElementsByName('opcion');

Métodos Modernos con Selectores CSS (Query Selectors)

Estos métodos son más versátiles y potentes, ya que permiten usar cualquier selector CSS para encontrar elementos. Son los más recomendados en la mayoría de los casos.

  • document.querySelector('selector-css'): Devuelve el primer elemento que coincide con el selector CSS especificado. Si no encuentra ninguno, devuelve null.
  • document.querySelectorAll('selector-css'): Devuelve una NodeList de todos los elementos que coinciden con el selector CSS especificado. Si no encuentra ninguno, devuelve una NodeList vacía.
⚠️ Advertencia: `querySelector` solo devuelve el *primer* elemento encontrado. Si necesitas todos, usa `querySelectorAll`. Además, las `HTMLCollection` y `NodeList` devueltas por estos métodos NO son arrays reales. Necesitarás convertirlas a array si quieres usar métodos de array (como `forEach`, `map`, `filter`), por ejemplo con `Array.from(nodeList)` o `[...nodeList]`.
// HTML de ejemplo:
// <div id="miDiv" class="contenedor principal">Hola Mundo</div>
// <p class="texto-resaltado">Este es un párrafo.</p>
// <p class="texto-resaltado">Otro párrafo.</p>
// <ul id="listaCompras">
//   <li class="item">Manzanas</li>
//   <li class="item">Leche</li>
// </ul>

const miDivPorSelector = document.querySelector('#miDiv');
console.log(miDivPorSelector); // Selecciona el div con ID 'miDiv'

const primerParrafoResaltado = document.querySelector('.texto-resaltado');
console.log(primerParrafoResaltado); // Selecciona solo el primer párrafo con clase 'texto-resaltado'

const todosLosItemsLista = document.querySelectorAll('#listaCompras .item');
console.log(todosLosItemsLista); // NodeList de los items de la lista

todosLosItemsLista.forEach(item => {
  console.log(item.textContent); // Iterar sobre los items
});

✍️ Modificando Elementos del DOM

Una vez que hemos seleccionado uno o varios elementos, podemos empezar a modificarlos. Esto incluye cambiar su contenido, sus atributos, sus estilos y su estructura.

Modificando Contenido

Existen varias propiedades para cambiar el contenido de un elemento:

  • element.textContent: Obtiene o establece el contenido de texto del nodo y sus descendientes. Es seguro contra ataques de inyección de HTML.
  • element.innerHTML: Obtiene o establece el contenido HTML del nodo. Permite insertar HTML, pero cuidado con la seguridad (potenciales ataques XSS si se usa con entrada de usuario sin sanear).
  • element.outerHTML: Obtiene o establece el HTML del elemento completo, incluyendo el propio elemento y sus descendientes. Al establecerlo, el elemento original es reemplazado por el nuevo contenido.
const titulo = document.querySelector('h1');
const parrafo = document.getElementById('miParrafo');
const contenedor = document.querySelector('.contenedor');

// Cambiar texto de un título
titulo.textContent = 'Nuevo Título Dinámico';

// Insertar HTML en un párrafo (¡usar con precaución!)
parrafo.innerHTML = 'Este es un párrafo con <strong>texto en negrita</strong>.';

// Reemplazar un elemento completamente
// contenedor.outerHTML = '<section class="nueva-seccion">Contenido nuevo</section>';
// ¡Cuidado! Después de esta línea, 'contenedor' ya no hace referencia al elemento original

Manipulando Atributos

Podemos modificar los atributos de un elemento (como src, href, class, id, data-*).

  • element.getAttribute('nombre-atributo'): Obtiene el valor de un atributo.
  • element.setAttribute('nombre-atributo', 'nuevo-valor'): Establece el valor de un atributo. Si el atributo no existe, lo crea.
  • element.removeAttribute('nombre-atributo'): Elimina un atributo.
  • element.hasAttribute('nombre-atributo'): Comprueba si un atributo existe (devuelve true o false).

Para atributos de clase específicos, hay propiedades y métodos más convenientes:

  • element.className: Obtiene o establece la cadena de todas las clases del elemento.
  • element.classList: Un objeto DOMTokenList que permite añadir, eliminar, alternar o comprobar clases individuales de forma más sencilla.

Tabla comparativa de className vs classList:

Característicaelement.classNameelement.classList
Tipo de datoString (lista de clases separadas por espacios)DOMTokenList (objeto con métodos para manipular clases)
Añadir claseselement.className += ' nueva-clase'element.classList.add('nueva-clase')
Eliminar claseselement.className = 'otra-clase' (reescribe)element.classList.remove('clase-a-eliminar')
Alternar clasesNo directoelement.classList.toggle('clase-a-alternar')
Comprobar claseselement.className.includes('clase')element.classList.contains('clase')
Múltiples claseselement.className += ' clase1 clase2'element.classList.add('clase1', 'clase2')
📌 Nota: Siempre que sea posible, usa `classList` para manipular las clases. Es más robusto, flexible y evita errores comunes al trabajar con cadenas de texto.
const imagen = document.querySelector('img');

// Cambiar el src de una imagen
imagen.setAttribute('src', 'nueva-imagen.jpg');
imagen.setAttribute('alt', 'Descripción de la nueva imagen');

// Añadir una clase
imagen.classList.add('imagen-redondeada');

// Eliminar una clase
imagen.classList.remove('oculto');

// Alternar una clase (si está, la quita; si no está, la pone)
imagen.classList.toggle('activo');

// Comprobar si tiene una clase
if (imagen.classList.contains('imagen-redondeada')) {
  console.log('La imagen es redondeada.');
}

Modificando Estilos CSS

Podemos cambiar los estilos CSS directamente desde JavaScript usando la propiedad style de un elemento.

  • element.style.propiedadCSS: Establece o obtiene el valor de una propiedad CSS. Las propiedades CSS con guiones (font-size) se convierten a camelCase (fontSize).
const miBoton = document.getElementById('miBoton');

miBoton.style.backgroundColor = 'blue';
miBoton.style.color = 'white';
miBoton.style.padding = '10px 20px';
miBoton.style.border = 'none';
miBoton.style.borderRadius = '5px';

// Obtener un estilo computado (el estilo final después de todas las reglas CSS)
const estiloComputado = window.getComputedStyle(miBoton);
console.log(estiloComputado.backgroundColor); // blue
🔥 Importante: Es preferible manipular clases CSS en lugar de estilos inline directos con `element.style`. Esto promueve una mejor separación de responsabilidades y facilita la gestión de estilos. Por ejemplo, en lugar de `element.style.color = 'red'`, crea una clase `.text-red { color: red; }` y luego usa `element.classList.add('text-red')`.

🏗️ Creando y Eliminando Elementos del DOM

La manipulación no se limita a modificar lo que ya existe; también podemos crear nuevos elementos y nodos de texto, y eliminar los existentes.

Creando Nuevos Elementos

  • document.createElement('nombre-de-etiqueta'): Crea un nuevo elemento HTML del tipo especificado.
  • document.createTextNode('contenido de texto'): Crea un nuevo nodo de texto.

Una vez creado, un elemento no está en el documento hasta que lo adjuntamos a un padre.

Añadiendo Elementos al DOM

  • parentNode.appendChild(childNode): Añade un nodo como el último hijo del parentNode.
  • parentNode.insertBefore(newNode, referenceNode): Inserta newNode antes de referenceNode dentro de parentNode.
  • parentNode.prepend(nodeOrDOMString): Inserta nodos o cadenas de texto al principio del parentNode.
  • element.insertAdjacentElement(position, element): Inserta un elemento en una posición específica relativa al elemento de referencia. Las posiciones pueden ser 'beforebegin', 'afterbegin', 'beforeend', 'afterend'.
  • element.insertAdjacentHTML(position, htmlString): Similar a insertAdjacentElement, pero para insertar una cadena HTML.
  • element.insertAdjacentText(position, textString): Similar, pero para insertar texto plano.
const contenedorPrincipal = document.getElementById('app');

// Crear un nuevo párrafo
const nuevoParrafo = document.createElement('p');
nuevoParrafo.textContent = 'Este es un párrafo creado dinámicamente.';
nuevoParrafo.classList.add('dinamico');

// Añadirlo al final del contenedor principal
contenedorPrincipal.appendChild(nuevoParrafo);

// Crear un nuevo div con un título y texto
const nuevaSeccion = document.createElement('div');
nuevaSeccion.classList.add('tarjeta');

const tituloSeccion = document.createElement('h3');
tituloSeccion.textContent = 'Sección Creada';
nuevaSeccion.appendChild(tituloSeccion);

const textoSeccion = document.createElement('p');
textoSeccion.textContent = 'Contenido de la nueva sección con createElement.';
nuevaSeccion.appendChild(textoSeccion);

// Añadirlo al principio del contenedor principal
contenedorPrincipal.prepend(nuevaSeccion);

// Crear un item de lista y añadirlo a una lista existente
const lista = document.getElementById('miLista'); // Suponiendo <ul id="miLista"> existe
const nuevoItem = document.createElement('li');
nuevoItem.textContent = 'Nuevo Item de Lista';
lista.appendChild(nuevoItem);

// Insertar un elemento antes de otro específico
const primerItem = lista.firstElementChild; // Obtener el primer <li>
const itemAntesPrimero = document.createElement('li');
itemAntesPrimero.textContent = 'Item antes del primero';
lista.insertBefore(itemAntesPrimero, primerItem);

// Usando insertAdjacentHTML
contenedorPrincipal.insertAdjacentHTML('beforeend', '<p class="mensaje">¡Contenido añadido con `insertAdjacentHTML`!</p>');

Eliminando Elementos del DOM

  • parentNode.removeChild(childNode): Elimina un hijo específico del parentNode.
  • element.remove(): Un método más moderno y conciso para que un elemento se elimine a sí mismo de su padre.
const elementoAEliminar = document.getElementById('elementoAntiguo');

// Opción 1: Usando removeChild (requiere el padre)
// elementoAEliminar.parentNode.removeChild(elementoAEliminar);

// Opción 2: Usando remove() (más sencillo)
if (elementoAEliminar) { // Asegurarse de que el elemento existe antes de intentar eliminarlo
  elementoAEliminar.remove();
}

// Eliminar todos los elementos con una clase específica
const elementosParaQuitar = document.querySelectorAll('.obsoleto');
elementosParaQuitar.forEach(el => el.remove());

👂 Eventos del DOM: Reaccionando a la Interacción del Usuario

La verdadera interactividad llega con los eventos del DOM. JavaScript puede "escuchar" lo que sucede en la página (clics, pulsaciones de teclas, movimiento del ratón, carga de la página, etc.) y ejecutar código en respuesta.

Conceptos Básicos de Eventos

  • Eventos: Acciones o sucesos que ocurren en el navegador (ej. click, mouseover, keydown, load, submit).
  • Manejadores de Eventos (Event Handlers): Funciones de JavaScript que se ejecutan cuando ocurre un evento.
  • Escuchadores de Eventos (Event Listeners): Mecanismos para adjuntar manejadores de eventos a elementos.

addEventListener(): La Forma Recomendada

El método addEventListener() es la forma estándar y más flexible de registrar manejadores de eventos. Permite añadir múltiples manejadores para el mismo evento en el mismo elemento, y desacopla el JavaScript del HTML.

element.addEventListener(evento, funcionManejadora, [opciones])

  • evento: Un string con el nombre del evento (ej. 'click', 'mouseover', 'submit').
  • funcionManejadora: La función que se ejecutará cuando ocurra el evento.
  • opciones (opcional): Un objeto con opciones como capture (fase de captura/burbujeo), once (se ejecuta una sola vez), passive (para eventos de scroll para mejorar el rendimiento).
const miBoton = document.getElementById('miBoton');
const cuadroTexto = document.getElementById('cuadroTexto');
const formulario = document.getElementById('miFormulario');

// Evento de click en un botón
miBoton.addEventListener('click', () => {
  alert('¡Botón clickeado!');
  miBoton.style.backgroundColor = 'green';
});

// Evento de cambio en un input de texto
cuadroTexto.addEventListener('input', (event) => {
  console.log('Texto actual:', event.target.value);
  document.getElementById('displayTexto').textContent = event.target.value;
});

// Evento submit de un formulario
formulario.addEventListener('submit', (event) => {
  event.preventDefault(); // Evita el envío del formulario y la recarga de la página
  console.log('Formulario enviado (simulado).');
  const nombre = document.getElementById('nombreInput').value;
  alert(`Hola, ${nombre}!`);
});

removeEventListener()

Es importante saber cómo eliminar escuchadores de eventos para evitar fugas de memoria, especialmente en aplicaciones de una sola página (SPAs) o cuando los elementos se eliminan del DOM.

element.removeEventListener(evento, funcionManejadora, [opciones])

⚠️ Advertencia: Para que `removeEventListener()` funcione, la función manejadora debe ser la *misma referencia* a la función que se adjuntó. No puedes usar una función anónima si planeas eliminarla.
const miBotonClick = document.getElementById('miBotonClick');

function handleClick() {
  alert('¡Haz hecho click!');
}

miBotonClick.addEventListener('click', handleClick);

// Después de un tiempo o bajo cierta condición, podemos eliminar el listener
// setTimeout(() => {
//   miBotonClick.removeEventListener('click', handleClick);
//   console.log('Listener de click eliminado.');
// }, 5000);

El Objeto Evento (event)

Cuando un evento se dispara, el navegador crea un objeto Event y lo pasa como el primer argumento a la función manejadora. Este objeto contiene información valiosa sobre el evento:

  • event.type: El tipo de evento ('click', 'keydown', etc.).
  • event.target: El elemento DOM que originó el evento (el elemento en el que se hizo click, por ejemplo).
  • event.currentTarget: El elemento al que se adjuntó el escuchador de eventos.
  • event.preventDefault(): Detiene la acción por defecto del navegador para ese evento (ej. evitar el envío de un formulario, la navegación de un enlace).
  • event.stopPropagation(): Detiene la propagación del evento a los elementos padres (burbujeo).

Delegación de Eventos

La delegación de eventos es una técnica muy útil para manejar eventos en elementos que se añaden dinámicamente o cuando se tienen muchos elementos similares. En lugar de adjuntar un escuchador a cada elemento, adjuntamos uno al padre común.

Cuando un evento burbujea hacia arriba en el DOM, podemos detectar qué elemento descendente lo originó usando event.target y actuar en consecuencia.

Delegación de Eventos Contenedor <UL> Elemento con el Event Listener Elemento <LI> 1 Elemento <LI> 2 Elemento <LI> 3 CLICK Burbujeo Manejador UL const target = event.target; Identifica que el click provino del LI 2 El evento viaja desde el LI hasta el UL por propagación (bubbling)
const listaArticulos = document.getElementById('listaArticulos'); // Un <ul>

listaArticulos.addEventListener('click', (event) => {
  // Comprobar si el click fue en un <li> dentro de la lista
  if (event.target.tagName === 'LI') {
    alert('Has clickeado en: ' + event.target.textContent);
    event.target.classList.toggle('seleccionado');
  }
});

// Incluso si añadimos nuevos LI después, el listener del UL los manejará
// const nuevoLi = document.createElement('li');
// nuevoLi.textContent = 'Artículo Nuevo';
// listaArticulos.appendChild(nuevoLi);
💡 Consejo: La delegación de eventos mejora el rendimiento, especialmente con listas largas o elementos generados dinámicamente, ya que solo se adjunta un único escuchador.

🎯 Ejemplos Prácticos y Casos de Uso

Vamos a aplicar lo aprendido en algunos escenarios comunes.

1. Contador Sencillo

Un botón para incrementar un número y mostrarlo en la pantalla.

<!-- HTML -->
<div id="contador-app">
  <h2>Contador: <span id="valorContador">0</span></h2>
  <button id="btnIncrementar">Incrementar</button>
</div>
// JavaScript
const valorContadorSpan = document.getElementById('valorContador');
const btnIncrementar = document.getElementById('btnIncrementar');
let contador = 0;

btnIncrementar.addEventListener('click', () => {
  contador++;
  valorContadorSpan.textContent = contador;
  if (contador % 5 === 0) {
    valorContadorSpan.style.color = 'blue';
  } else {
    valorContadorSpan.style.color = 'black';
  }
});

2. Alternar Visibilidad de un Elemento (Toggle)

Mostrar u ocultar un div al hacer clic en un botón.

<!-- HTML -->
<div>
  <button id="btnToggle">Mostrar/Ocultar Texto</button>
  <div id="contenidoOculto" style="display: none; padding: 10px; border: 1px solid #ccc;">
    ¡Este es el contenido que se muestra u oculta!
  </div>
</div>
// JavaScript
const btnToggle = document.getElementById('btnToggle');
const contenidoOculto = document.getElementById('contenidoOculto');

btnToggle.addEventListener('click', () => {
  if (contenidoOculto.style.display === 'none') {
    contenidoOculto.style.display = 'block';
  } else {
    contenidoOculto.style.display = 'none';
  }
  // Mejor aún, usar classList.toggle con una clase CSS para display: none/block
  // contenidoOculto.classList.toggle('oculto'); 
  // CSS: .oculto { display: none; }
});

3. Lista de Tareas (TODO List) Dinámica

Un ejemplo más complejo que involucra crear y eliminar elementos.

<!-- HTML -->
<div class="todo-app">
  <h1>Mi Lista de Tareas</h1>
  <input type="text" id="nuevaTareaInput" placeholder="Añadir nueva tarea...">
  <button id="btnAnadirTarea">Añadir</button>
  <ul id="listaTareas">
    <!-- Las tareas se añadirán aquí -->
  </ul>
</div>
// JavaScript
const nuevaTareaInput = document.getElementById('nuevaTareaInput');
const btnAnadirTarea = document.getElementById('btnAnadirTarea');
const listaTareasUL = document.getElementById('listaTareas');

btnAnadirTarea.addEventListener('click', anadirTarea);
nuevaTareaInput.addEventListener('keypress', (event) => {
  if (event.key === 'Enter') {
    anadirTarea();
  }
});

function anadirTarea() {
  const textoTarea = nuevaTareaInput.value.trim();

  if (textoTarea !== '') {
    const listItem = document.createElement('li');
    listItem.innerHTML = `
      <span>${textoTarea}</span>
      <button class="btn-eliminar">X</button>
    `;
    
    // Delegación de eventos para el botón eliminar
    const btnEliminar = listItem.querySelector('.btn-eliminar');
    btnEliminar.addEventListener('click', () => {
      listItem.remove();
    });

    listaTareasUL.appendChild(listItem);
    nuevaTareaInput.value = ''; // Limpiar input
  } else {
    alert('Por favor, introduce una tarea.');
  }
}

// Si tuvieras muchos botones de eliminar o tareas existentes, 
// la delegación de eventos en el UL sería más eficiente para los botones de eliminar también.
/*
listaTareasUL.addEventListener('click', (event) => {
  if (event.target.classList.contains('btn-eliminar')) {
    event.target.closest('li').remove();
  }
});
*/

4. Cambiar Atributo de una Imagen

Un botón que cambia la fuente de una imagen.

<!-- HTML -->
<div>
  <img id="imagen" src="imagen1.jpg" alt="Imagen inicial" width="200">
  <button id="btnCambiarImagen">Cambiar Imagen</button>
</div>
// JavaScript
const imagenElemento = document.getElementById('imagen');
const btnCambiarImagen = document.getElementById('btnCambiarImagen');
let esImagen1 = true;

btnCambiarImagen.addEventListener('click', () => {
  if (esImagen1) {
    imagenElemento.setAttribute('src', 'imagen2.jpg');
    imagenElemento.setAttribute('alt', 'Segunda imagen');
  } else {
    imagenElemento.setAttribute('src', 'imagen1.jpg');
    imagenElemento.setAttribute('alt', 'Imagen inicial');
  }
  esImagen1 = !esImagen1;
});

🚀 Buenas Prácticas y Rendimiento

La manipulación del DOM puede ser costosa en términos de rendimiento, ya que cada cambio puede provocar que el navegador tenga que recalcular el diseño y volver a pintar la página (reflow y repaint). Aquí hay algunas buenas prácticas:

  • Minimiza las manipulaciones directas: Si vas a hacer muchos cambios, intenta agruparlos. Por ejemplo, crea un fragmento de documento (document.createDocumentFragment()), añade todos los elementos a él, y luego adjunta el fragmento al DOM de una sola vez.
  • Manipula elementos 'off-DOM': Si vas a hacer muchas modificaciones a un elemento, a veces es más eficiente eliminarlo temporalmente del DOM, hacer las modificaciones y luego reinsertarlo.
  • Usa classList para estilos: Como se mencionó, es más eficiente y mantenible manipular clases CSS en lugar de estilos inline directos.
  • Delegación de eventos: Reduce el número de escuchadores de eventos, mejorando la memoria y el rendimiento.
  • Caché de selecciones: Si vas a acceder al mismo elemento varias veces, guárdalo en una variable en lugar de seleccionarlo repetidamente.
// Ejemplo de uso de DocumentFragment para optimizar adición de múltiples elementos
const listaGrande = document.getElementById('listaGrande'); // Suponemos <ul id="listaGrande"> existe
const fragmento = document.createDocumentFragment();

for (let i = 0; i < 1000; i++) {
  const listItem = document.createElement('li');
  listItem.textContent = `Elemento ${i + 1}`;
  fragmento.appendChild(listItem);
}

listaGrande.appendChild(fragmento); // Solo un 'reflow' y 'repaint' al final
Más sobre DocumentFragment Un `DocumentFragment` es un objeto DOM ligero, una versión 'mínima' o 'ligera' de `Document` que no es parte del árbol de documentos activo. Esto significa que cuando se realizan cambios en un `DocumentFragment`, no afectan directamente al documento principal, y no provocan redibujados (reflows) o repintados (repaints) costosos en el navegador. Una vez que todas las modificaciones se han completado, el fragmento puede ser adjuntado al DOM, lo que resulta en una única operación de reflow/repaint.

✅ Conclusión

La manipulación del DOM es el corazón de la interactividad web con JavaScript. Desde seleccionar elementos hasta modificar su contenido, atributos y estilos, pasando por la creación dinámica y la respuesta a eventos, has explorado las herramientas esenciales para dar vida a tus páginas web.

Recuerda la importancia de las buenas prácticas para escribir código eficiente y mantenible. Con estos conocimientos, estás listo para construir experiencias de usuario ricas y dinámicas. ¡Ahora, a practicar!

Tutorial Completado

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!