Manipulación del DOM en JavaScript: cómo seleccionar y cambiar el HTML de tu página

Por Gonzalo Rodríguez de Austria · Publicado el 2026-10-23 09:15:22 · 8 min de lectura

En el artículo de objetos ya vimos que JavaScript representa casi todo como un objeto con propiedades y métodos. La página que estás viendo ahora mismo no es una excepción: el navegador la representa internamente como un objeto gigante — el DOM — y puedes leerlo y cambiarlo con el mismo JavaScript que ya conoces. En este artículo vemos qué es el DOM, cómo seleccionar elementos de la página, cómo leer y cambiar su contenido y estilos, y cómo crear o eliminar elementos sobre la marcha.

Si ya sabes guardar datos en variables, tomar decisiones con condicionales, organizar código en funciones y agrupar datos en arrays y objetos, esto es el paso que lo conecta todo con una página web real: hasta ahora tu código solo hablaba con la consola; a partir de aquí habla con el HTML.

Qué es el DOM

Cuando el navegador carga una página HTML, no se queda con el texto tal cual lo escribiste: construye una representación interna en forma de árbol, donde cada etiqueta es un nodo. A esa representación se le llama DOM (Document Object Model, "modelo de objetos del documento"). Es lo que permite que el navegador dibuje la página en pantalla, y también es lo que te permite a ti, con JavaScript, leer y modificar esa página después de que se haya cargado.

En el navegador, el DOM de la página actual está disponible a través de un objeto global llamado document. Todo lo que vas a hacer en este artículo pasa por ese objeto: seleccionar elementos, leer su contenido, cambiarlo, o crear elementos nuevos y añadirlos al árbol.

Seleccionar elementos: querySelector y querySelectorAll

Antes de poder cambiar algo en la página, necesitas una referencia a ese elemento guardada en una variable. La forma recomendada hoy en día es document.querySelector(), que acepta un selector CSS — el mismo tipo de selector que usarías en una hoja de estilos — y devuelve el primer elemento que coincide:

const titulo = document.querySelector("h1");
const boton = document.querySelector(".btn-principal");
const campo = document.querySelector("#email");

Si necesitas todos los elementos que coinciden, no solo el primero, usa document.querySelectorAll(). Te devuelve una NodeList, que se comporta como un array para la mayoría de cosas que ya sabes hacer, incluido recorrerla con forEach o con el for...of que ya conoces:

const parrafos = document.querySelectorAll("p");

parrafos.forEach(function (parrafo) {
  console.log(parrafo.textContent);
});

También existen métodos más antiguos como document.getElementById() o document.getElementsByTagName(), que todavía verás en código de otros programadores. Funcionan, pero querySelector y querySelectorAll hacen lo mismo y más, así que son los que te interesa usar por defecto.

Leer y cambiar contenido: textContent vs innerHTML

Una vez tienes la referencia a un elemento, puedes leer o cambiar lo que hay dentro con dos propiedades que se confunden con facilidad:

PropiedadQué haceCuándo usarla
textContentLee o escribe solo el texto, sin interpretar HTMLCasi siempre — es la opción segura
innerHTMLLee o escribe el HTML interno, interpretando etiquetasSolo cuando necesitas insertar HTML de verdad
const aviso = document.querySelector("#aviso");

aviso.textContent = "Guardado correctamente";          // texto plano
aviso.innerHTML = "Guardado <strong>correctamente</strong>"; // HTML real

La diferencia importa más de lo que parece: si usas innerHTML con un texto que viene de un usuario (un comentario, un campo de un formulario), estás dejando que ese texto se interprete como HTML — y eso es justo lo que permite ataques de tipo XSS, donde alguien mete código malicioso en un campo de texto. Si solo necesitas mostrar texto, usa siempre textContent.

Cambiar atributos y estilos

Los atributos HTML (src, href, alt, disabled...) se leen y modifican con getAttribute() y setAttribute(), o directamente como propiedad del elemento en los casos más comunes:

const imagen = document.querySelector("img");

imagen.setAttribute("src", "/nueva-foto.jpg");
imagen.alt = "Foto actualizada"; // equivalente, para atributos habituales

Para estilos, tienes dos caminos. El primero es escribir estilos directamente desde JavaScript con la propiedad style:

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

caja.style.backgroundColor = "tomato";
caja.style.display = "none";

Fíjate en que las propiedades CSS con guion, como background-color, se escriben en JavaScript en camelCase: backgroundColor. El segundo camino, casi siempre preferible, es no tocar estilos sueltos desde JavaScript y en su lugar añadir o quitar una clase CSS que ya tenga esos estilos definidos en tu hoja de estilos:

caja.classList.add("oculto");
caja.classList.remove("oculto");
caja.classList.toggle("oculto"); // la añade si no está, la quita si está

Esto mantiene tus estilos en el CSS, donde deben estar, y tu JavaScript solo decide cuándo se aplican, no cómo son.

Reaccionar a clics: una primera toma de contacto con los eventos

Todo lo anterior no sirve de mucho si solo se ejecuta una vez al cargar la página. Lo normal es que esos cambios ocurran en respuesta a algo que hace el usuario, como un clic. Para eso usas addEventListener(), que le dice a un elemento "cuando pase esto, ejecuta esta función":

const boton = document.querySelector("#guardar");

boton.addEventListener("click", function () {
  aviso.textContent = "Guardado correctamente";
});

La función que le pasas a addEventListener() no es distinta de las funciones que ya sabes crear: aquí simplemente se la entregas al navegador para que la ejecute él cuando ocurra el clic. Esto es solo lo mínimo para que los ejemplos de este artículo cobren sentido; los eventos dan para un artículo propio más adelante, con todos sus tipos y matices.

Crear elementos nuevos: createElement y appendChild

Hasta ahora has modificado elementos que ya existían en el HTML. Pero también puedes crear elementos desde cero con JavaScript y añadirlos a la página:

const lista = document.querySelector("#lista-tareas");

const item = document.createElement("li");
item.textContent = "Repasar el artículo de objetos";

lista.appendChild(item);

createElement() crea el elemento, pero no lo coloca en ningún sitio por sí solo — sigue "flotando" en memoria hasta que lo añades al árbol con appendChild(), que lo mete al final de otro elemento como su último hijo.

Eliminar elementos del DOM

Para quitar un elemento de la página basta con llamar a remove() sobre la referencia que tengas guardada:

const item = document.querySelector(".completada");

item.remove();

En código antiguo verás también padre.removeChild(hijo), que hace lo mismo pero exige tener una referencia al elemento padre. remove() es más directo y es lo que te interesa usar hoy.

Ejemplo práctico: una lista que se actualiza sola

Juntando todo lo anterior, así es como construirías una lista de tareas muy simple que añade un elemento nuevo cada vez que se pulsa un botón:

const boton = document.querySelector("#anadir");
const campo = document.querySelector("#tarea");
const lista = document.querySelector("#lista-tareas");

boton.addEventListener("click", function () {
  const texto = campo.value;

  if (texto.trim() === "") return; // sin esto, se añadirían tareas vacías

  const item = document.createElement("li");
  item.textContent = texto;

  lista.appendChild(item);
  campo.value = "";
});

Fíjate en el if (texto.trim() === "") return; del principio: es exactamente la misma lógica de los condicionales que ya conoces, solo que aquí decide si vale la pena seguir ejecutando la función. Esto es, en esencia, lo que hace cualquier lista de tareas, carrito de la compra o feed que se actualiza sin recargar la página: seleccionar, crear, añadir — con algún evento disparando el proceso.

Errores típicos al empezar

  • Seleccionar un elemento antes de que exista en el HTML. Si tu <script> se ejecuta antes de que el navegador haya leído el resto de la página, querySelector devuelve null. Coloca el script al final del <body>, o usa el atributo defer.
  • Usar innerHTML cuando basta con textContent. Además del riesgo de seguridad, es más lento, porque obliga al navegador a volver a interpretar HTML.
  • Olvidar que querySelectorAll devuelve una lista, no un único elemento. Si intentas hacer elementos.textContent = "..." directamente sobre el resultado, no funciona: tienes que recorrerla.
  • Crear un elemento con createElement y olvidarse de añadirlo con appendChild. El elemento existe en memoria, pero no aparece en la página porque nunca se insertó en el árbol.

En resumen

  • El DOM es la representación en forma de árbol de tu HTML, accesible desde JavaScript a través de document.
  • Para seleccionar elementos, usa querySelector() (uno) o querySelectorAll() (varios).
  • Para leer o cambiar contenido, usa textContent por defecto; reserva innerHTML para cuando necesites insertar HTML real.
  • Para estilos, prefiere añadir o quitar clases con classList antes que tocar style directamente.
  • addEventListener() conecta todo esto con lo que hace el usuario, como un clic.
  • Para añadir elementos nuevos: createElement() los crea, appendChild() los coloca en la página.
  • Para quitarlos: remove().

Con esto ya puedes hacer que una página reaccione y cambie sin recargarse, que es la base de cualquier interfaz interactiva. El siguiente paso natural es trabajar con datos reales — convertirlos a JSON para guardarlos o enviarlos a un servidor, o guardarlos directamente en el navegador con localStorage — para que esa lista de tareas, por ejemplo, no se borre cada vez que recargas la página.

Tambien te puede interesar

Comentarios

Todavía no hay comentarios. ¡Sé el primero en opinar!

Deja tu comentario