Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Navegación por el árbol DOM JS: API del DOM

La forma más sencilla de familiarizarse con el árbol DOM es estudiar su estructura.

En resumen, el árbol DOM está compuesto por nodos. Juntos, los nodos forman una jerarquía similar a la de HTML. Los nodos se dividen en dos tipos:

  • Nodos hoja: no contienen otros nodos en su interior.
  • Nodos internos: tienen nodos dentro de ellos.

En su mayoría, los nodos específicos describen etiquetas específicas de HTML y contienen sus atributos dentro de ellos. Los nodos tienen un tipo que determina el conjunto de propiedades y métodos del nodo. En esta lección nos familiarizaremos con ellos.

El elemento raíz en el árbol DOM corresponde a la etiqueta <html>. Puedes acceder a él de la siguiente manera:

const html = document.documentElement;
// La propiedad tagName del nodo contiene el nombre de la etiqueta en mayúsculas
console.log(html.tagName); // => 'HTML'

// Contenido de la etiqueta HTML como nodos del árbol DOM
// El texto también se representa como un nodo
html.childNodes; // [head, text, body]

// Porque head está antes que body
html.firstChild; // <head>...</head>
html.lastChild; // <body>...</body>

// Segundo nodo, acceso por índice
html.childNodes[1]; // #text

Nodo raíz del árbol DOM

Las etiquetas <body> y <head> siempre están presentes en el documento, por lo que se pueden acceder directamente a ellas a través del objeto document para facilitar el acceso:

document.head;
document.body;

Además de descender por el árbol, también se puede ascender:

// El padre de body es html
document.documentElement === document.body.parentNode; // true
document.body === document.body.childNodes[2].parentNode; // true

Si representamos el árbol, podemos movernos hacia arriba y hacia abajo, así como hacia la izquierda y hacia la derecha. La siguiente imagen ilustra esto:

Relaciones entre nodos en el árbol DOM

childNodes

A continuación, veremos childNodes, una propiedad que permite obtener los nodos hijos, es decir, los nodos que están directamente dentro del nodo actual. También se les llama descendientes de primer nivel.

Al trabajar con childNodes, hay algunos aspectos interesantes:

  1. Esta propiedad es de solo lectura. Intentar escribir algo en un elemento específico no tendrá éxito:

    // No habrá errores, pero no cambiará nada
    document.body.childNodes[0] = 'hey';
    

    Se puede modificar el árbol DOM utilizando métodos especiales, que se estudiarán en la lección correspondiente.

  2. Aunque childNodes devuelve un conjunto de elementos, no es un array. No tiene los métodos familiares como map(), filter(), entre otros. Sin embargo, tiene forEach():

    // Tipo NodeList
    const nodes = document.documentElement.childNodes;
    
    nodes.forEach((el) => console.log(el));
    

    Si realmente lo deseas, puedes convertirlo en un array y luego trabajar con él de la manera habitual:

    const list = Array.from(nodes);
    // Ahora tenemos un array normal y los métodos disponibles, como filter
    // Podemos filtrar los elementos deseados
    const filtered = list.filter((item) => item.textContent.includes('Navegación por el DOM'));
    // Y extraer datos de ellos, como los nombres de las etiquetas
    const filteredTags = filtered.map((item) => item.tagName);
    console.log(filteredTags); // => ['HEAD', 'BODY']
    

Jerarquía

Los nodos del árbol DOM se dividen en tipos por una razón. Estos tipos se organizan en una jerarquía de lo general a lo específico. En la jerarquía, los subtipos heredan las propiedades y métodos de los tipos padres y agregan los suyos propios:

Árbol DOM

// La forma más sencilla de ver el tipo
document.body.toString(); // "[object HTMLBodyElement]"
document.body instanceof HTMLBodyElement; // true

Los nodos de tipo Text y Comment son nodos hoja, lo que significa que no pueden tener descendientes. Por otro lado, los elementos o los tipos derivados de Element son los que más se utilizan. Los elementos incluyen todos los tipos representados por etiquetas en HTML.

Al trabajar con el árbol, naturalmente surge el concepto de descendientes. En el contexto del árbol DOM, esto significa que una etiqueta con contenido tiene descendientes.

Echemos un vistazo a un ejemplo de código:

const html = `
  <html>
    <head></head>
    <body>
      <div id="parent-div">
        <h1>Título</h1>
        ¡Hola!
        <div class="child-div">
          <span>Algo de <b>texto</b></span>
          <ol>
            <li>1</li>
            <li>2</li>
          </ol>
          <!-- Fin de la lista -->
        </div>
      </div>
    </body>
  </html>
`;

En este ejemplo, la etiqueta <div> (con id parent-div) tiene 14 descendientes y tres nodos hijos. Veamos cuál es la diferencia entre estos conceptos.

Solo se consideran hijos aquellos nodos que están directamente dentro del nodo padre en el primer nivel de anidamiento. Por lo tanto, se considerarán hijos:

  • <h1>
  • El texto "¡Hola!"
  • <div> con la clase child-div

Se llaman descendientes solo a los nodos que están directamente dentro del nodo padre. Por lo tanto, los descendientes del nodo <div> (con id parent-div) no solo son los tres nodos hijos mencionados anteriormente, sino también todos los nodos dentro de ellos:

Hijos y descendientes en el árbol DOM

Los nodos hijos también son descendientes. Sin embargo, lo contrario no es cierto: un descendiente no necesariamente es un hijo. En nuestro ejemplo, la etiqueta <span> es un descendiente, pero no es un elemento hijo en relación con la etiqueta <div> con id parent-div.

Elementos

En la práctica, a menudo estamos interesados no en cualquier nodo, sino en los elementos. Son los que manipulamos y a través de los cuales nos movemos. Esto es tan importante que en el DOM hay una forma alternativa de recorrer el árbol que se basa únicamente en elementos:

Relaciones entre elementos en el árbol DOM

Todas estas propiedades devuelven objetos de tipo Element y omiten objetos de tipo Text o Comment. Esto se puede ver en el siguiente ejemplo, donde la propiedad children devuelve solo las etiquetas.

Esto diferencia a children de childNodes, que devuelve todos los nodos, incluidos los nodos hoja:

const node = document.documentElement;
node.children; // [head, body]

Entre children y childNodes también hay otra diferencia bastante importante. No solo devuelven diferentes conjuntos de nodos, sino que el tipo de colección en el primer y segundo caso también es diferente:

  • childNodes devuelve un NodeList.
  • children devuelve un HTMLCollection.

Funcionan de manera ligeramente diferente, pero veremos esta diferencia más adelante, cuando aprendamos sobre selectores.

Algunos elementos tienen propiedades especiales para navegar a través de ellos, como los formularios y las tablas:

<table>
  <tr>
    <td>1.1</td>
    <td>1.2</td>
    <td>1.3</td>
  </tr>
  <tr>
    <td>2.1</td>
    <td>2.2</td>
    <td>2.3</td>
  </tr>
</table>
const table = document.body.firstElementChild
table.rows[0].cells[2];

Este método de navegación no reemplaza los métodos principales. Está diseñado únicamente para facilitar la navegación en lugares donde tiene sentido.

Conclusión

¿Es necesario conocer todos estos métodos de memoria? En realidad, no. Es importante comprender los principios generales de la estructura del árbol DOM, conocer la jerarquía de tipos y cómo se realiza el recorrido de los elementos de manera fundamental. Siempre se pueden consultar los métodos y propiedades específicos en la documentación. No tiene sentido recordarlos de memoria y no hay beneficio práctico en hacerlo.

Además, recorrer el árbol de esta manera es un enfoque de bajo nivel. En la práctica, para seleccionar los elementos deseados, se utilizan selectores, que se estudiarán más adelante.


Trabajo independiente

  1. Abre la consola en tu navegador.
  2. Comenzando desde document.body, navega hasta los nodos más profundos que contengan este texto.

Materiales adicionales

  1. Node / MDN Web Docs

Para acceder completo a curso necesitas un plan básico

El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY