Selección de elementos DOM

Intermedio
JavaScript
JavaScript
Actualizado: 16/05/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

Selectores por ID y nombre de etiqueta: Métodos específicos y su rendimiento

La selección de elementos es una de las operaciones más fundamentales cuando trabajamos con el DOM en JavaScript. Antes de poder manipular un elemento, necesitamos primero obtener una referencia a él. JavaScript proporciona métodos específicos para seleccionar elementos por su ID o por el nombre de su etiqueta, que son las formas más básicas y directas de acceder a elementos del DOM.

Selección por ID con getElementById()

El método getElementById() es la forma más eficiente de seleccionar un elemento único en el DOM. Este método busca un elemento que tenga el atributo id especificado y devuelve una referencia directa a ese elemento.

// Seleccionar un elemento con id="mainHeader"
const header = document.getElementById("mainHeader");

// Ahora podemos manipular el elemento
if (header) {
  header.style.color = "blue";
  header.textContent = "Nuevo título";
}

Características importantes de getElementById():

  • Rendimiento óptimo: Es el método de selección más rápido disponible, ya que los IDs deben ser únicos en el documento.
  • Devuelve null si no encuentra ningún elemento con el ID especificado.
  • No requiere prefijo # como en los selectores CSS.
  • Ámbito limitado: Solo está disponible en el objeto document, no en elementos individuales.

Selección por nombre de etiqueta con getElementsByTagName()

Cuando necesitamos seleccionar múltiples elementos del mismo tipo, getElementsByTagName() nos permite obtener todos los elementos de una etiqueta HTML específica.

// Seleccionar todos los párrafos del documento
const paragraphs = document.getElementsByTagName("p");

// Iterar sobre la colección de elementos
for (let i = 0; i < paragraphs.length; i++) {
  paragraphs[i].classList.add("text-paragraph");
}

Este método devuelve una HTMLCollection viva, lo que significa que se actualiza automáticamente cuando se añaden o eliminan elementos del DOM que coinciden con el selector.

También podemos limitar la búsqueda a un contexto específico, aplicando el método a un elemento en lugar de al documento completo:

// Seleccionar solo los párrafos dentro de un div específico
const container = document.getElementById("content");
const contentParagraphs = container.getElementsByTagName("p");

Selección por nombre de clase con getElementsByClassName()

Similar al método anterior, getElementsByClassName() nos permite seleccionar elementos basándonos en el valor de su atributo class.

// Seleccionar todos los elementos con la clase "highlight"
const highlights = document.getElementsByClassName("highlight");

// Aplicar estilos a todos los elementos seleccionados
for (const element of highlights) {
  element.style.backgroundColor = "yellow";
}

Al igual que getElementsByTagName(), este método devuelve una HTMLCollection viva y puede aplicarse a un elemento específico para limitar el ámbito de búsqueda.

Consideraciones de rendimiento

El rendimiento de los selectores es un factor importante a considerar, especialmente en aplicaciones con DOM complejos:

  • getElementById(): Es el método más rápido, con complejidad O(1) en la mayoría de implementaciones.
  • getElementsByTagName(): Tiene buen rendimiento, pero depende del número de elementos en el documento.
  • getElementsByClassName(): Similar a getElementsByTagName() en rendimiento.

Una comparativa básica de rendimiento sería:

// Más rápido - Selección directa por ID
const element = document.getElementById("uniqueId");

// Rápido - Selección por nombre de etiqueta
const divs = document.getElementsByTagName("div");

// También rápido - Selección por clase
const items = document.getElementsByClassName("item");

Estrategias para mejorar el rendimiento

Para optimizar el rendimiento de las selecciones DOM:

  • Limita el ámbito de búsqueda cuando sea posible, seleccionando primero un contenedor y luego buscando dentro de él.
  • Almacena referencias a elementos que uses frecuentemente en lugar de seleccionarlos repetidamente.
  • Minimiza las manipulaciones del DOM agrupando cambios cuando sea posible.
// Enfoque ineficiente - Selecciona el mismo elemento múltiples veces
document.getElementById("menu").style.display = "block";
document.getElementById("menu").classList.add("active");
document.getElementById("menu").setAttribute("aria-expanded", "true");

// Enfoque optimizado - Selecciona el elemento una sola vez
const menu = document.getElementById("menu");
menu.style.display = "block";
menu.classList.add("active");
menu.setAttribute("aria-expanded", "true");

Estos métodos específicos de selección proporcionan una base sólida para interactuar con el DOM. Aunque existen métodos más flexibles como querySelector(), los selectores por ID y nombre de etiqueta siguen siendo fundamentales por su simplicidad y rendimiento, especialmente en situaciones donde la estructura del DOM es conocida y estable.

¿Te está gustando esta lección?

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

Selectores avanzados con CSS: Potencia y flexibilidad de querySelector/All

Mientras que los métodos tradicionales como getElementById() y getElementsByTagName() ofrecen un rendimiento óptimo para casos específicos, JavaScript moderno nos proporciona herramientas más versátiles para seleccionar elementos DOM mediante la sintaxis de selectores CSS. Los métodos querySelector() y querySelectorAll() representan un salto cualitativo en la flexibilidad de selección de elementos.

querySelector(): Selección precisa con sintaxis CSS

El método querySelector() permite seleccionar el primer elemento que coincida con un selector CSS específico, combinando la potencia de los selectores CSS con la simplicidad de una API unificada.

// Seleccionar el primer párrafo dentro de un artículo
const firstParagraph = document.querySelector("article p");

// Seleccionar un elemento por ID usando sintaxis CSS
const header = document.querySelector("#mainHeader");

// Seleccionar por clase
const activeItem = document.querySelector(".active");

La verdadera fortaleza de querySelector() se revela cuando necesitamos selectores complejos que serían difíciles o imposibles con los métodos tradicionales:

// Seleccionar el segundo elemento li dentro de una lista ordenada
const secondItem = document.querySelector("ol li:nth-child(2)");

// Seleccionar inputs de tipo checkbox que estén marcados
const checkedBoxes = document.querySelector("input[type='checkbox']:checked");

// Seleccionar elementos con múltiples clases
const specialButton = document.querySelector(".btn.primary.large");

querySelectorAll(): Colecciones completas con selectores avanzados

Cuando necesitamos seleccionar múltiples elementos que coincidan con un patrón, querySelectorAll() nos proporciona esta capacidad devolviendo una NodeList con todos los elementos que cumplen el criterio:

// Seleccionar todos los enlaces externos
const externalLinks = document.querySelectorAll("a[href^='http']");

// Seleccionar todos los párrafos impares
const oddParagraphs = document.querySelectorAll("p:nth-child(odd)");

// Combinar múltiples selectores con comas
const headings = document.querySelectorAll("h1, h2, h3");

Selectores de atributos y pseudoclases

Una de las ventajas más significativas de estos métodos es el acceso completo a los selectores de atributos y pseudoclases de CSS:

// Elementos con un atributo específico
const elementsWithData = document.querySelectorAll("[data-role]");

// Elementos con un valor de atributo específico
const menuItems = document.querySelectorAll("[data-section='menu']");

// Elementos con atributos que contienen un valor
const imageItems = document.querySelectorAll("[class*='img']");

// Elementos que están en hover (útil en ciertos contextos)
const hoverElements = document.querySelectorAll(":hover");

Contexto de selección y encadenamiento

Al igual que con los métodos tradicionales, podemos limitar el ámbito de búsqueda aplicando estos métodos a un elemento específico en lugar de al documento completo:

// Primero seleccionamos un contenedor
const sidebar = document.querySelector(".sidebar");

// Luego buscamos dentro de ese contenedor
const sidebarLinks = sidebar.querySelectorAll("a");
const activeTab = sidebar.querySelector(".tab.active");

Este enfoque de encadenamiento mejora significativamente el rendimiento en documentos grandes y complejos, ya que reduce el ámbito de búsqueda.

Combinadores de selectores CSS

Los métodos querySelector y querySelectorAll admiten todos los combinadores de CSS, lo que permite selecciones estructurales precisas:

// Descendientes (espacios): todos los spans dentro de divs
const nestedSpans = document.querySelectorAll("div span");

// Hijos directos (>): solo los párrafos que son hijos directos de secciones
const directChildren = document.querySelectorAll("section > p");

// Hermanos adyacentes (+): elementos que siguen inmediatamente a otros
const labelsAfterInputs = document.querySelectorAll("input + label");

// Hermanos generales (~): todos los elementos que siguen a otros
const allAfterHeader = document.querySelectorAll("h2 ~ p");

Consideraciones de rendimiento

Aunque estos métodos son extremadamente flexibles, es importante entender sus implicaciones de rendimiento:

  • Son generalmente más lentos que los métodos específicos como getElementById().
  • La complejidad del selector afecta directamente al rendimiento.
  • querySelectorAll() devuelve una NodeList estática (a diferencia de las HTMLCollection vivas).
// Más específico y eficiente
const menu = document.querySelector("#mainMenu");

// Menos eficiente (escanea todo el DOM)
const menu = document.querySelector("nav.primary ul.menu");

Estrategias de optimización

Para aprovechar la flexibilidad sin sacrificar demasiado rendimiento:

  • Usa selectores lo más específicos posible.
  • Prefiere IDs cuando estén disponibles, incluso dentro de querySelector().
  • Limita el ámbito de búsqueda seleccionando primero un contenedor.
  • Almacena referencias a elementos que selecciones frecuentemente.
// Enfoque optimizado para selecciones repetidas
const productList = document.querySelector(".products");
const featuredProducts = productList.querySelectorAll(".featured");
const productImages = productList.querySelectorAll("img.product-image");

Los métodos querySelector() y querySelectorAll() representan un equilibrio entre flexibilidad y rendimiento, permitiéndonos utilizar toda la potencia de los selectores CSS para interactuar con el DOM de manera más expresiva y precisa. Esta capacidad es especialmente valiosa en aplicaciones modernas donde la estructura del DOM puede ser dinámica y compleja.

Colecciones y NodeLists: Características, diferencias y conversión a arrays

Cuando seleccionamos múltiples elementos del DOM, JavaScript nos devuelve estructuras de datos especiales que contienen referencias a esos elementos. Estas estructuras, principalmente HTMLCollection y NodeList, son fundamentales para entender cómo manipular eficientemente grupos de elementos del DOM.

Tipos de colecciones DOM

JavaScript maneja principalmente dos tipos de colecciones cuando trabajamos con múltiples elementos del DOM:

  • HTMLCollection: Devuelta por métodos como getElementsByTagName() y getElementsByClassName()
  • NodeList: Devuelta por querySelectorAll() y algunos métodos nativos como childNodes

Aunque ambas parecen similares a primera vista, tienen diferencias importantes que afectan cómo trabajamos con ellas.

HTMLCollection: Colecciones vivas

Una HTMLCollection es una colección dinámica que se actualiza automáticamente cuando el DOM cambia. Esto significa que si añadimos o eliminamos elementos que coinciden con el criterio de selección original, la colección reflejará estos cambios sin necesidad de volver a ejecutar el selector.

// Obtener todos los divs como HTMLCollection
const divs = document.getElementsByTagName("div");
console.log(divs.length); // Muestra el número actual de divs

// Si añadimos un nuevo div al DOM
const newDiv = document.createElement("div");
document.body.appendChild(newDiv);

// La colección se actualiza automáticamente
console.log(divs.length); // Muestra un número mayor

Características principales de HTMLCollection:

  • Es una colección viva que refleja cambios en el DOM en tiempo real
  • Proporciona acceso a elementos por índice numérico (collection[0])
  • Ofrece acceso por nombre o ID si están disponibles (collection.namedItem("elementId"))
  • No tiene métodos de array como forEach, map, etc.
  • Solo contiene elementos HTML (no comentarios ni nodos de texto)

NodeList: Más completa y versátil

Una NodeList es una colección de nodos del DOM que puede ser estática o viva dependiendo de cómo se obtenga:

// NodeList estática (no se actualiza con cambios en el DOM)
const paragraphs = document.querySelectorAll("p");

// NodeList viva (se actualiza automáticamente)
const childNodes = document.body.childNodes;

Características principales de NodeList:

  • Puede contener cualquier tipo de nodo DOM (elementos, texto, comentarios)
  • Proporciona acceso por índice numérico (nodeList[0])
  • Incluye el método forEach() en navegadores modernos
  • No incluye otros métodos de array como map() o filter()
  • Puede ser estática (querySelectorAll) o viva (childNodes)
// Usando forEach en NodeList
const links = document.querySelectorAll("a");
links.forEach(link => {
  link.target = "_blank";
});

Diferencias clave entre HTMLCollection y NodeList

Entender las diferencias entre estas colecciones es crucial para trabajar eficientemente con el DOM:

| Característica | HTMLCollection | NodeList | |----------------|---------------|----------| | Naturaleza | Siempre viva | Puede ser estática o viva | | Contenido | Solo elementos HTML | Cualquier tipo de nodo DOM | | Métodos de array | No incluye | Incluye forEach() | | Acceso | Por índice y nombre/ID | Solo por índice | | Uso común | getElementsBy... | querySelectorAll() |

Conversión a arrays para mayor flexibilidad

Una práctica común es convertir estas colecciones a arrays JavaScript nativos para aprovechar todos los métodos de manipulación de arrays:

// Convertir HTMLCollection a array
const divCollection = document.getElementsByTagName("div");
const divArray = Array.from(divCollection);

// Alternativa con operador spread
const divArray2 = [...divCollection];

// Ahora podemos usar métodos de array
const visibleDivs = divArray.filter(div => 
  div.style.display !== "none"
);

const divTexts = divArray.map(div => div.textContent);

La conversión a arrays nos permite:

  • Usar métodos de array como map(), filter(), reduce()
  • Aplicar desestructuración y otras características modernas de JavaScript
  • Crear una copia estática de una colección viva
  • Encadenar operaciones de forma más legible

Casos de uso prácticos

Veamos algunos escenarios comunes donde es útil entender y manipular estas colecciones:

// Filtrar elementos con cierta clase
const items = document.getElementsByClassName("item");
const activeItems = [...items].filter(item => 
  item.classList.contains("active")
);

// Transformar una colección en datos estructurados
const formFields = document.querySelectorAll("form input, form select");
const formData = [...formFields].reduce((data, field) => {
  data[field.name] = field.value;
  return data;
}, {});

// Modificar elementos de forma condicional
const paragraphs = document.querySelectorAll("p");
paragraphs.forEach((p, index) => {
  if (index % 2 === 0) {
    p.classList.add("even");
  } else {
    p.classList.add("odd");
  }
});

Rendimiento y consideraciones prácticas

Al trabajar con colecciones DOM, es importante considerar el rendimiento:

  • Minimiza las conversiones innecesarias a arrays si no necesitas métodos de array
  • Almacena en caché las colecciones y arrays si los vas a utilizar repetidamente
  • Ten en cuenta que las colecciones vivas tienen un coste de rendimiento al mantenerse actualizadas
  • Para operaciones simples en NodeList, usa el método nativo forEach() en lugar de convertir
// Enfoque eficiente para operaciones simples
const links = document.querySelectorAll("a");
links.forEach(link => link.rel = "noopener");

// Conversión justificada para operaciones complejas
const headings = [...document.querySelectorAll("h1, h2, h3")]
  .filter(h => h.offsetParent !== null)  // Solo visibles
  .map(h => ({
    level: parseInt(h.tagName[1]),
    text: h.textContent,
    id: h.id
  }));

Entender las características y diferencias entre HTMLCollection y NodeList, así como saber cuándo y cómo convertirlas a arrays, es esencial para manipular eficientemente múltiples elementos del DOM en aplicaciones JavaScript modernas.

Aprendizajes de esta lección

  • Conocer los métodos de selección de elementos: getElementById() y getElementsByTagName().
  • Comprender el rendimiento y eficiencia de cada método.
  • Diferenciar entre HTMLCollection y NodeList.
  • Aplicar estrategias para optimizar el rendimiento del DOM mediante selección eficiente.

Completa JavaScript y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración