Modificación de contenido y atributos
Introducción
Una vez que hemos aprendido a seleccionar elementos del DOM, el siguiente paso natural es modificarlos. La modificación dinámica del contenido y los atributos de los elementos HTML es lo que hace que las páginas web sean interactivas y respondan a las acciones del usuario. En este artículo, exploraremos las diferentes formas de modificar el texto, el HTML, los atributos y las clases CSS de los elementos seleccionados. Estas técnicas son fundamentales para crear experiencias web dinámicas y atractivas.
Modificación de contenido de texto
JavaScript nos ofrece varias formas de manipular el contenido textual de los elementos. Las dos propiedades principales son textContent
e innerText
:
La propiedad textContent
Esta propiedad permite acceder o modificar el contenido de texto de un elemento, incluyendo todo el texto contenido en el elemento y sus descendientes:
// HTML: <div id="mensaje">Hola <span>mundo</span></div>
const mensaje = document.getElementById("mensaje");
// Leer el contenido de texto
console.log(mensaje.textContent); // "Hola mundo"
// Modificar el contenido de texto
mensaje.textContent = "Nuevo texto";
// Ahora el HTML es: <div id="mensaje">Nuevo texto</div>
Características importantes:
- Devuelve todo el texto, incluyendo espacios y saltos de línea
- Ignora el marcado HTML (lo trata como texto plano)
- Es más eficiente que
innerHTML
La propiedad innerText
Similar a textContent
, pero tiene en cuenta la presentación CSS:
// HTML:
// <div id="ejemplo">
// Texto visible
// <span style="display: none">Texto oculto</span>
// </div>
const ejemplo = document.getElementById("ejemplo");
console.log(ejemplo.textContent); // "Texto visible Texto oculto"
console.log(ejemplo.innerText); // "Texto visible"
Diferencias con textContent
:
innerText
solo devuelve el texto visible (respeta CSS)innerText
respeta los saltos de línea visiblesinnerText
es más lento porque necesita calcular estilos
Propiedades innerHTML vs textContent
La propiedad innerHTML
permite trabajar con el contenido HTML de un elemento:
// HTML: <div id="contenedor">Texto <b>importante</b></div>
const contenedor = document.getElementById("contenedor");
// Leer el HTML interno
console.log(contenedor.innerHTML); // "Texto <b>importante</b>"
// Modificar el HTML interno
contenedor.innerHTML = "Texto <i>actualizado</i>";
// Ahora el HTML es: <div id="contenedor">Texto <i>actualizado</i></div>
Comparación de usos:
const elemento = document.getElementById("ejemplo");
// Con textContent (trata todo como texto)
elemento.textContent = "<b>Texto en negrita</b>";
// Resultado: El usuario ve literalmente: "<b>Texto en negrita</b>"
// Con innerHTML (interpreta el HTML)
elemento.innerHTML = "<b>Texto en negrita</b>";
// Resultado: El usuario ve: "Texto en negrita" (en negrita)
Consideraciones de seguridad con innerHTML
Es importante mencionar que innerHTML
puede representar un riesgo de seguridad si se utiliza con contenido no confiable:
// PELIGROSO: Nunca uses innerHTML con datos proporcionados por usuarios
const comentarioUsuario = "<script>alert('código malicioso')</script>";
elemento.innerHTML = comentarioUsuario; // Potencial ataque XSS
Para contenido generado por usuarios, es más seguro usar textContent
.
Manipulación de atributos HTML
Atributos estándar
Para trabajar con atributos HTML estándar, podemos usar varios métodos:
const enlace = document.getElementById("mi-enlace");
// Obtener un atributo
const url = enlace.getAttribute("href");
console.log(url); // Por ejemplo: "https://ejemplo.com"
// Establecer un atributo
enlace.setAttribute("href", "https://nueva-url.com");
enlace.setAttribute("target", "_blank");
// Comprobar si existe un atributo
if (enlace.hasAttribute("rel")) {
console.log("El enlace tiene un atributo rel");
}
// Eliminar un atributo
enlace.removeAttribute("target");
Acceso directo a atributos comunes
Muchos atributos estándar tienen acceso directo como propiedades:
const imagen = document.getElementById("mi-imagen");
// Acceso directo a atributos comunes
imagen.src = "nueva-imagen.jpg";
imagen.alt = "Descripción de la imagen";
const formulario = document.getElementById("mi-formulario");
formulario.action = "/procesar";
formulario.method = "post";
Esta forma es más concisa y generalmente preferible para atributos estándar.
Manipulación de atributos data-*
Los atributos personalizados data-*
son muy útiles para almacenar información adicional en elementos HTML:
// HTML: <div id="producto" data-id="123" data-categoria="electronica">iPhone</div>
const producto = document.getElementById("producto");
// Acceder a atributos data-*
const id = producto.dataset.id; // "123"
const categoria = producto.dataset.categoria; // "electronica"
// Modificar atributos data-*
producto.dataset.precio = "999";
producto.dataset.disponible = "true";
// Comprobar si existe un atributo data-*
if ("precio" in producto.dataset) {
console.log("El producto tiene precio definido");
}
// Eliminar un atributo data-*
delete producto.dataset.disponible;
Los atributos data-*
son perfectos para almacenar información que necesitamos en JavaScript sin afectar la presentación.
Modificación de clases CSS
La manipulación de clases CSS es una de las formas más comunes de modificar la apariencia de los elementos.
La propiedad className
La forma tradicional de modificar clases es mediante la propiedad className
:
const elemento = document.getElementById("mi-elemento");
// Leer las clases actuales
console.log(elemento.className); // Por ejemplo: "boton primario"
// Sobrescribir todas las clases
elemento.className = "boton secundario";
Sin embargo, este enfoque sobrescribe todas las clases existentes, lo que no siempre es deseable.
El objeto classList
El objeto classList
proporciona métodos más precisos para manejar clases:
const boton = document.getElementById("mi-boton");
// Añadir una clase
boton.classList.add("destacado");
// Eliminar una clase
boton.classList.remove("inactivo");
// Alternar una clase (la añade si no existe, la elimina si existe)
boton.classList.toggle("seleccionado");
// Comprobar si tiene una clase específica
if (boton.classList.contains("primario")) {
console.log("Es un botón primario");
}
// Reemplazar una clase por otra
boton.classList.replace("error", "exito");
El objeto classList
es mucho más versátil y es la forma recomendada de trabajar con clases en JavaScript moderno.
Manipulación de estilos directos
Aunque generalmente es mejor usar clases CSS para controlar la apariencia, a veces necesitamos modificar estilos directamente mediante la propiedad style
:
const caja = document.getElementById("mi-caja");
// Establecer estilos individuales
caja.style.backgroundColor = "skyblue";
caja.style.width = "200px";
caja.style.padding = "20px";
caja.style.borderRadius = "10px";
// Notar que las propiedades CSS con guiones se convierten a camelCase
// Por ejemplo: background-color -> backgroundColor
// Leer un estilo inline específico
console.log(caja.style.backgroundColor); // "skyblue"
Importante: la propiedad style
solo accede y modifica los estilos inline (definidos directamente en el atributo style
del elemento HTML). No refleja los estilos definidos en hojas de estilo CSS.
Obtener estilos computados
Para obtener los estilos reales aplicados (de cualquier origen):
const elemento = document.getElementById("ejemplo");
const estilos = window.getComputedStyle(elemento);
const colorActual = estilos.getPropertyValue("color");
const tamanoFuente = estilos.fontSize; // También se puede acceder con notación de punto
console.log(`Color: ${colorActual}, Tamaño: ${tamanoFuente}`);
Modificación de valores de formularios
Los elementos de formulario tienen propiedades específicas para acceder y modificar sus valores:
// Input de texto
const nombreInput = document.getElementById("nombre");
nombreInput.value = "Juan Pérez";
// Checkbox
const aceptaTerminos = document.getElementById("terminos");
aceptaTerminos.checked = true;
// Radio button
const opcionHombre = document.getElementById("genero-hombre");
opcionHombre.checked = true;
// Select
const selectPais = document.getElementById("pais");
selectPais.value = "es"; // Selecciona la opción con value="es"
// Select (alternativa)
selectPais.selectedIndex = 2; // Selecciona la tercera opción (índice 2)
// Textarea
const comentarios = document.getElementById("comentarios");
comentarios.value = "Nuevo comentario";
// Deshabilitar un campo
nombreInput.disabled = true;
// Hacer un campo de solo lectura
comentarios.readOnly = true;
Buenas prácticas de modificación
- Minimiza las manipulaciones del DOM: Cada modificación puede causar reflow/repaint.
// Mal (causa múltiples reflow)
for (let i = 0; i < 100; i++) {
contenedor.innerHTML += `<div>${i}</div>`;
}
// Bien (una sola modificación al DOM)
let contenidoHTML = "";
for (let i = 0; i < 100; i++) {
contenidoHTML += `<div>${i}</div>`;
}
contenedor.innerHTML = contenidoHTML;
-
Usa classList en lugar de className cuando solo necesites modificar clases específicas.
-
Preferir cambios de clase sobre estilos inline: Es más mantenible y eficiente.
// Menos recomendado
elemento.style.backgroundColor = "red";
elemento.style.fontWeight = "bold";
// Más recomendado
elemento.classList.add("error-destacado");
// Y definir esos estilos en CSS: .error-destacado { background-color: red; font-weight: bold; }
- Evita innerHTML con contenido no confiable: Usa alternativas más seguras:
// Mejor alternativa a innerHTML para contenido dinámico
const nuevoElemento = document.createElement("div");
nuevoElemento.textContent = contenidoUsuario;
contenedor.appendChild(nuevoElemento);
Ejemplos prácticos
Ejemplo 1: Sistema de notificaciones
function mostrarNotificacion(mensaje, tipo) {
const notificacion = document.getElementById("notificacion");
// Establecer contenido
notificacion.textContent = mensaje;
// Resetear clases y añadir la que corresponda al tipo
notificacion.className = "notificacion";
notificacion.classList.add(tipo); // tipo puede ser "exito", "error", "aviso"
// Hacer visible
notificacion.style.display = "block";
// Ocultar automáticamente después de 3 segundos
setTimeout(() => {
notificacion.style.display = "none";
}, 3000);
}
// Uso
mostrarNotificacion("Datos guardados correctamente", "exito");
Ejemplo 2: Cambio de tema (claro/oscuro)
function cambiarTema() {
const body = document.body;
const botonTema = document.getElementById("boton-tema");
// Alternar clase en el body
body.classList.toggle("tema-oscuro");
// Actualizar texto del botón según el tema actual
if (body.classList.contains("tema-oscuro")) {
botonTema.textContent = "Cambiar a tema claro";
botonTema.setAttribute("aria-pressed", "true");
} else {
botonTema.textContent = "Cambiar a tema oscuro";
botonTema.setAttribute("aria-pressed", "false");
}
// Guardar preferencia en localStorage
const temaActual = body.classList.contains("tema-oscuro") ? "oscuro" : "claro";
localStorage.setItem("tema-preferido", temaActual);
}
Ejemplo 3: Validación de formulario en tiempo real
const campoEmail = document.getElementById("email");
campoEmail.addEventListener("blur", function() {
// Expresión regular simple para validar email
const esValido = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.value);
if (!esValido && this.value !== "") {
// Marcar como inválido
this.classList.add("invalid");
// Añadir mensaje de error si no existe
if (!this.nextElementSibling || !this.nextElementSibling.classList.contains("error-mensaje")) {
const mensajeError = document.createElement("div");
mensajeError.textContent = "Por favor, introduce un email válido";
mensajeError.className = "error-mensaje";
this.insertAdjacentElement("afterend", mensajeError);
}
} else {
// Quitar marca de inválido
this.classList.remove("invalid");
// Eliminar mensaje de error si existe
if (this.nextElementSibling && this.nextElementSibling.classList.contains("error-mensaje")) {
this.nextElementSibling.remove();
}
}
});
Resumen
En este artículo hemos explorado las diferentes formas de modificar elementos del DOM: cambiar su contenido de texto, modificar su HTML interno, manipular atributos, gestionar clases CSS y modificar estilos directamente. También hemos visto cómo trabajar con elementos de formulario y algunas buenas prácticas para realizar estas modificaciones de manera eficiente.
Estas técnicas son fundamentales para crear interacciones dinámicas y responder a las acciones del usuario en páginas web. En el próximo artículo, aprenderemos cómo crear y eliminar elementos del DOM, lo que nos permitirá modificar la estructura misma de nuestra página de forma dinámica.