Selección de elementos del DOM
Introducción
La manipulación del DOM (Document Object Model) es una de las tareas fundamentales en el desarrollo web con JavaScript. Para poder interactuar con cualquier elemento de una página web, primero debemos ser capaces de seleccionarlo. En este artículo aprenderemos las diferentes formas de seleccionar elementos del DOM, desde los métodos tradicionales hasta los selectores modernos. Dominar estas técnicas es esencial para crear páginas web dinámicas y aplicaciones interactivas.
Métodos de selección por ID
El identificador (ID) es un atributo único que podemos asignar a un elemento HTML. Para seleccionar un elemento por su ID, utilizamos el método getElementById()
:
// HTML: <div id="contenedor">Contenido</div>
const contenedor = document.getElementById("contenedor");
console.log(contenedor); // Muestra el elemento div en la consola
Características importantes:
- Devuelve un único elemento o
null
si no existe - Es el método más rápido de selección
- Los IDs deben ser únicos en la página
Métodos de selección por clase
Para seleccionar elementos que comparten una misma clase CSS, utilizamos getElementsByClassName()
:
// HTML:
// <p class="destacado">Párrafo 1</p>
// <p class="destacado">Párrafo 2</p>
const elementosDestacados = document.getElementsByClassName("destacado");
console.log(elementosDestacados.length); // Muestra: 2
console.log(elementosDestacados[0]); // Muestra el primer párrafo
Características importantes:
- Devuelve una colección HTML (similar a un array)
- La colección se actualiza automáticamente si cambia el DOM
- Devuelve una colección vacía si no hay coincidencias
Métodos de selección por etiqueta
Para seleccionar todos los elementos de un tipo específico (por ejemplo, todos los párrafos), utilizamos getElementsByTagName()
:
// Selecciona todos los párrafos del documento
const parrafos = document.getElementsByTagName("p");
// Recorremos la colección
for (let i = 0; i < parrafos.length; i++) {
console.log(parrafos[i].textContent);
}
Este método también devuelve una colección HTML viva que se actualiza automáticamente cuando cambia el DOM.
Selectores CSS con querySelector
El método querySelector()
nos permite utilizar selectores CSS para encontrar elementos, lo que ofrece una gran flexibilidad:
// Selecciona el primer párrafo dentro de un div con clase "contenido"
const parrafoEspecifico = document.querySelector("div.contenido p");
// Selecciona el primer elemento con la clase "boton-principal"
const boton = document.querySelector(".boton-principal");
// Selecciona el elemento con id "cabecera"
const cabecera = document.querySelector("#cabecera");
Características importantes:
- Devuelve el primer elemento que coincide con el selector
- Devuelve
null
si no hay coincidencias - Permite selectores CSS complejos
- Es más versátil pero generalmente más lento que los métodos específicos
Selección múltiple con querySelectorAll
Cuando necesitamos seleccionar varios elementos que coincidan con un selector CSS, utilizamos querySelectorAll()
:
// Selecciona todos los enlaces dentro de la navegación
const enlacesMenu = document.querySelectorAll("nav a");
// Recorremos con forEach (a diferencia de getElementsBy... esto retorna un NodeList)
enlacesMenu.forEach(enlace => {
console.log(enlace.href);
});
// Selecciona todos los inputs de tipo checkbox que estén marcados
const casillasSeleccionadas = document.querySelectorAll("input[type='checkbox']:checked");
El método devuelve un NodeList, que es similar a un array pero no es un array completo. Sin embargo, admite el método forEach()
en navegadores modernos.
Navegación por el árbol DOM
Una vez que tenemos un elemento seleccionado, podemos navegar por sus elementos relacionados:
const elemento = document.getElementById("mi-elemento");
// Acceso a elementos padre
const padre = elemento.parentElement;
// Acceso a hijos
const hijos = elemento.children; // Colección de elementos hijos
const primerHijo = elemento.firstElementChild;
const ultimoHijo = elemento.lastElementChild;
// Acceso a hermanos
const hermanoAnterior = elemento.previousElementSibling;
const hermanoSiguiente = elemento.nextElementSibling;
Colecciones de elementos HTML
Los métodos getElementsByClassName()
, getElementsByTagName()
y getElementsByName()
devuelven colecciones HTML (HTMLCollection) que tienen características específicas:
const botones = document.getElementsByClassName("boton");
// No podemos usar métodos de array como forEach directamente
// Esto NO funciona: botones.forEach(boton => { ... })
// Pero podemos iterar con un bucle for tradicional
for (let i = 0; i < botones.length; i++) {
botones[i].style.backgroundColor = "blue";
}
// O convertir a Array para usar métodos de array
Array.from(botones).forEach(boton => {
boton.addEventListener("click", function() {
console.log("Botón pulsado");
});
});
Diferencias entre NodeList y HTMLCollection
Es importante entender las diferencias entre estas colecciones:
-
HTMLCollection (devuelta por
getElementsBy...
):- Colección viva que se actualiza automáticamente
- Acceso solo por índice o por nombre/ID
- No tiene métodos como
forEach
-
NodeList (devuelta por
querySelectorAll
):- Colección estática (no se actualiza automáticamente)
- Tiene el método
forEach
en navegadores modernos - Puede contener diferentes tipos de nodos (elementos, texto, etc.)
// Ejemplo de actualización de HTMLCollection
const divs = document.getElementsByTagName("div");
console.log(divs.length); // Por ejemplo: 5
// Creamos un nuevo div
const nuevoDiv = document.createElement("div");
document.body.appendChild(nuevoDiv);
console.log(divs.length); // 6 - Se actualiza automáticamente
// Con NodeList no ocurre lo mismo
const divsNodeList = document.querySelectorAll("div");
console.log(divsNodeList.length); // 5
// Añadimos otro div
const otroDiv = document.createElement("div");
document.body.appendChild(otroDiv);
console.log(divsNodeList.length); // Sigue siendo 5 - No se actualiza
Buenas prácticas de selección
-
Usa el método más específico: Si conoces el ID, usa
getElementById()
en lugar dequerySelector("#id")
. -
Limita el alcance de la búsqueda: Busca dentro de contenedores específicos en lugar de todo el documento.
// En lugar de esto (busca en todo el documento)
const enlaces = document.querySelectorAll("a");
// Haz esto (limita la búsqueda a la navegación)
const navegacion = document.getElementById("menu-principal");
const enlaces = navegacion.querySelectorAll("a");
- Guarda referencias a elementos usados frecuentemente: Evita seleccionar el mismo elemento múltiples veces.
// Mala práctica
document.getElementById("formulario").style.backgroundColor = "white";
document.getElementById("formulario").addEventListener("submit", enviarDatos);
// Buena práctica
const formulario = document.getElementById("formulario");
formulario.style.backgroundColor = "white";
formulario.addEventListener("submit", enviarDatos);
- Utiliza atributos data para selección: En lugar de clases o IDs que mezclan presentación y comportamiento.
// HTML: <button data-accion="guardar">Guardar</button>
const botonGuardar = document.querySelector("[data-accion='guardar']");
Ejemplos prácticos
Ejemplo 1: Selección por relaciones familiares
// HTML:
// <ul id="lista">
// <li>Elemento 1</li>
// <li>Elemento 2</li>
// <li>Elemento 3</li>
// </ul>
const lista = document.getElementById("lista");
const primerElemento = lista.firstElementChild;
const ultimoElemento = lista.lastElementChild;
console.log(primerElemento.textContent); // "Elemento 1"
console.log(ultimoElemento.textContent); // "Elemento 3"
// Recorrer hermanos
let elementoActual = primerElemento;
while (elementoActual) {
console.log(elementoActual.textContent);
elementoActual = elementoActual.nextElementSibling;
}
Ejemplo 2: Selección combinada
// HTML:
// <div class="producto" id="prod-1" data-categoria="electronica">
// <h2>Teléfono</h2>
// <p class="precio">300€</p>
// </div>
// Múltiples maneras de seleccionar el precio
const precio1 = document.querySelector("#prod-1 .precio");
const precio2 = document.getElementById("prod-1").querySelector(".precio");
const precio3 = document.querySelector("[data-categoria='electronica'] p.precio");
console.log(precio1.textContent); // "300€"
Ejemplo 3: Selección y filtrado
// Seleccionar elementos por atributo
const camposObligatorios = document.querySelectorAll("input[required]");
// Convertir la NodeList a Array para usar métodos de filtrado
const camposTexto = Array.from(camposObligatorios).filter(
input => input.type === "text"
);
console.log(`Hay ${camposTexto.length} campos de texto obligatorios`);
Resumen
La selección de elementos del DOM es fundamental para la manipulación de páginas web con JavaScript. Hemos explorado diferentes métodos de selección, desde los más básicos como getElementById()
hasta los más versátiles como querySelector()
y querySelectorAll()
. También hemos aprendido a navegar por el árbol DOM utilizando propiedades como parentElement
, children
, y siblings
. Dominar estas técnicas nos permitirá crear interacciones más dinámicas y sofisticadas en nuestras páginas web.
En el siguiente artículo, aprenderemos cómo modificar el contenido y los atributos de los elementos que hemos seleccionado, lo que nos permitirá actualizar dinámicamente nuestra página web en respuesta a acciones del usuario o eventos del sistema.