JavaScript

JavaScript

Tutorial JavaScript: Introducción al DOM

DOM: Descubre cómo el Document Object Model permite interactuar y manipular elementos HTML con JavaScript. Aprende a optimizar tu código.

Aprende JavaScript y certifícate

Conceptos fundamentales: El DOM como interfaz de programación entre HTML y JavaScript

El Document Object Model (DOM) constituye el puente fundamental entre el código HTML que estructura una página web y el JavaScript que le otorga interactividad. En esencia, el DOM es una representación estructurada del documento HTML que permite a los programas acceder y modificar dinámicamente el contenido, estructura y estilo de una página web.

Cuando un navegador carga una página web, no solo interpreta el HTML para mostrar su contenido, sino que también crea una representación en memoria de ese documento en forma de árbol de objetos. Esta transformación convierte cada elemento HTML (como párrafos, divisiones, encabezados) en nodos manipulables mediante código JavaScript.

Función del DOM como interfaz

El DOM actúa como una API (Application Programming Interface) que establece un conjunto de reglas y métodos estandarizados para que JavaScript pueda:

  • Acceder a cualquier elemento de la página
  • Modificar el contenido de los elementos
  • Alterar los atributos y estilos
  • Crear nuevos elementos
  • Eliminar elementos existentes
  • Responder a eventos del usuario

Esta interfaz permite que el código JavaScript no necesite entender HTML directamente, sino que trabaje con una abstracción orientada a objetos del documento.

// Ejemplo básico de interacción con el DOM
const heading = document.createElement('h1');
heading.textContent = 'Hello DOM World!';
document.body.appendChild(heading);

En este ejemplo, no estamos manipulando texto HTML directamente, sino utilizando objetos y métodos del DOM para crear y añadir un nuevo elemento a la página.

Independencia del lenguaje

Aunque JavaScript es el lenguaje más común para manipular el DOM en navegadores web, es importante entender que el DOM es una especificación independiente del lenguaje. Sus principios fueron diseñados para ser utilizados con cualquier lenguaje de programación, lo que explica su estructura orientada a objetos y su terminología específica.

Estándares y compatibilidad

El DOM es mantenido por el World Wide Web Consortium (W3C) como un estándar abierto. Esto garantiza que los navegadores modernos implementen una interfaz consistente para la manipulación de documentos web. La especificación del DOM ha evolucionado a través de diferentes niveles o versiones:

  • DOM Nivel 1: Definió la estructura básica del modelo
  • DOM Nivel 2: Añadió soporte para espacios de nombres, eventos y estilos CSS
  • DOM Nivel 3: Mejoró el soporte para la carga y guardado de documentos

Los navegadores modernos implementan estas especificaciones, aunque pueden existir pequeñas diferencias en la implementación que ocasionalmente requieren técnicas de detección de características para garantizar la compatibilidad.

El DOM y el rendimiento

La manipulación del DOM es una operación costosa en términos de rendimiento. Cada vez que se modifica el DOM, el navegador debe recalcular la disposición de los elementos (reflow) y volver a pintar la pantalla (repaint).

// Enfoque ineficiente (múltiples manipulaciones del DOM)
for (let i = 0; i < 100; i++) {
  const paragraph = document.createElement('p');
  paragraph.textContent = `Paragraph ${i}`;
  document.body.appendChild(paragraph); // Causa reflow en cada iteración
}

// Enfoque optimizado (manipulación única del DOM)
const fragment = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
  const paragraph = document.createElement('p');
  paragraph.textContent = `Paragraph ${i}`;
  fragment.appendChild(paragraph);
}
document.body.appendChild(fragment); // Un solo reflow al final

Esta característica ha llevado al desarrollo de bibliotecas y frameworks como React, Vue o Angular, que implementan DOM virtuales o sistemas de renderizado optimizados para minimizar las manipulaciones directas del DOM.

El DOM vs. HTML

Es crucial entender que el DOM no es exactamente igual al código HTML original. El DOM:

  • Corrige automáticamente errores en el HTML
  • Añade elementos implícitos que pueden omitirse en HTML (como <tbody> en tablas)
  • Representa el estado actual de la página, que puede haber cambiado desde la carga inicial
// HTML original: <div></div>
// El DOM corrige automáticamente y representa:
console.log(document.querySelector('div').outerHTML); // <div></div>

// HTML original con error: <p>Texto<p>
// El DOM corrige y representa:
// <p>Texto</p><p></p>

Esta capacidad de representar y corregir el documento HTML es fundamental para entender cómo JavaScript interactúa con las páginas web a través del DOM.

Anatomía del árbol de nodos: Tipos de nodos y estructura jerárquica del documento

El DOM representa un documento HTML como una estructura de árbol donde cada parte del documento se convierte en un nodo. Esta organización jerárquica permite navegar eficientemente por el documento y manipular sus elementos de forma precisa.

Estructura jerárquica del DOM

Cuando un navegador procesa un documento HTML, construye una representación en memoria organizada como un árbol invertido. En la cima de esta estructura se encuentra el nodo document, que actúa como raíz de todo el árbol. A partir de ahí, se ramifica siguiendo la estructura anidada del HTML original.

// Estructura básica del árbol DOM
document
  └── html (elemento raíz)
      ├── head
      │   ├── title
      │   │   └── texto
      │   └── meta
      └── body
          ├── header
          │   └── h1
          │       └── texto
          └── div
              ├── p
              │   └── texto
              └── img

Esta estructura permite relaciones familiares entre nodos:

  • Nodo padre: El nodo que contiene directamente a otro nodo
  • Nodo hijo: Cualquier nodo contenido directamente dentro de otro
  • Nodos hermanos: Nodos que comparten el mismo padre
  • Descendientes: Todos los nodos contenidos dentro de un nodo (hijos, nietos, etc.)
  • Ancestros: Todos los nodos que contienen a un nodo (padre, abuelo, etc.)

Tipos de nodos en el DOM

El DOM define diferentes tipos de nodos, cada uno con propósitos específicos. Los más comunes son:

  • 1. Nodos de elemento (Element Node): Representan las etiquetas HTML como <div>, <p>, <span>. Son los bloques de construcción estructurales del documento.

  • 2. Nodos de texto (Text Node): Contienen el texto dentro de los elementos. Por ejemplo, en <p>Hola mundo</p>, "Hola mundo" es un nodo de texto hijo del elemento <p>.

  • 3. Nodos de atributo (Attribute Node): Representan los atributos de los elementos HTML como class, id o src.

  • 4. Nodos de comentario (Comment Node): Contienen los comentarios HTML (<!-- comentario -->).

  • 5. Nodo documento (Document Node): El nodo raíz que representa el documento entero.

  • 6. Nodo de tipo documento (DocumentType Node): Representa la declaración del tipo de documento (<!DOCTYPE html>).

  • 7. Nodos de fragmento (DocumentFragment Node): Contenedores ligeros que pueden almacenar partes del DOM sin formar parte del árbol principal.

// Explorando tipos de nodos
const element = document.querySelector('div'); // Nodo de elemento
const text = element.firstChild; // Posible nodo de texto
const attribute = element.attributes[0]; // Nodo de atributo
const comment = document.createComment('Esto es un comentario'); // Nodo de comentario
const fragment = document.createDocumentFragment(); // Nodo de fragmento

console.log(element.nodeType); // 1 (ELEMENT_NODE)
console.log(text.nodeType); // 3 (TEXT_NODE) si el primer hijo es texto
console.log(document.nodeType); // 9 (DOCUMENT_NODE)

Cada tipo de nodo está identificado por una constante numérica accesible mediante la propiedad nodeType. Estas constantes están definidas en la especificación DOM y son útiles para identificar programáticamente el tipo de nodo.

El DOM proporciona propiedades de navegación que permiten moverse entre nodos relacionados:

// Propiedades de navegación básicas
const parent = element.parentNode; // Nodo padre
const firstChild = element.firstChild; // Primer hijo (puede ser texto)
const lastChild = element.lastChild; // Último hijo
const nextSibling = element.nextSibling; // Hermano siguiente
const previousSibling = element.previousSibling; // Hermano anterior

// Propiedades que solo navegan entre elementos (ignorando nodos de texto y comentarios)
const firstElementChild = element.firstElementChild; // Primer elemento hijo
const children = element.children; // Colección de elementos hijos
const nextElementSibling = element.nextElementSibling; // Siguiente elemento hermano

Esta distinción entre propiedades que incluyen todos los nodos y las que solo consideran elementos es crucial para la navegación eficiente, ya que los espacios en blanco en el HTML se convierten en nodos de texto que pueden complicar la navegación.

Colecciones de nodos

El DOM utiliza colecciones especiales para representar grupos de nodos relacionados:

  • NodeList: Colección de nodos devuelta por métodos como querySelectorAll(). Puede ser estática o dinámica.
  • HTMLCollection: Colección de elementos HTML devuelta por propiedades como children o métodos como getElementsByClassName(). Siempre es dinámica.
// Diferencias entre colecciones
const staticNodeList = document.querySelectorAll('p'); // NodeList estática
const dynamicCollection = document.getElementsByTagName('p'); // HTMLCollection dinámica

// Si añadimos un nuevo párrafo:
const newP = document.createElement('p');
document.body.appendChild(newP);

console.log(staticNodeList.length); // No cambia (sigue igual)
console.log(dynamicCollection.length); // Aumenta (refleja el cambio)

Las colecciones dinámicas se actualizan automáticamente cuando el DOM cambia, mientras que las estáticas mantienen una instantánea del momento en que fueron creadas.

Nodos especiales y su función

Algunos nodos tienen funciones específicas en la estructura del documento:

  • El nodo documentElement (document.documentElement) representa el elemento <html>, la raíz del contenido del documento.
  • Los nodos head (document.head) y body (document.body) proporcionan acceso directo a estas secciones fundamentales.
  • Los nodos de fragmento (DocumentFragment) permiten construir estructuras DOM complejas fuera del árbol principal, mejorando el rendimiento.
// Acceso a nodos especiales
const htmlRoot = document.documentElement;
const headSection = document.head;
const bodySection = document.body;

// Uso de fragmentos para optimizar
const fragment = document.createDocumentFragment();
for (let i = 0; i < 3; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i}`;
  fragment.appendChild(li);
}
document.querySelector('ul').appendChild(fragment); // Una sola operación DOM

Whitespace nodes (nodos de espacio en blanco)

Un aspecto que suele causar confusión es que el formato del código HTML (indentación, saltos de línea) genera nodos de texto con espacios en blanco. Estos nodos son parte legítima del árbol DOM aunque no sean visibles en la página renderizada.

// HTML:
// <div>
//   <p>Texto</p>
// </div>

const div = document.querySelector('div');
console.log(div.childNodes.length); // 3 (no 1)
console.log(div.childNodes[0].nodeType); // 3 (TEXT_NODE, el salto de línea)
console.log(div.childNodes[1].nodeType); // 1 (ELEMENT_NODE, el párrafo)
console.log(div.childNodes[2].nodeType); // 3 (TEXT_NODE, el salto de línea)

Este comportamiento explica por qué a menudo es preferible usar propiedades como children o firstElementChild en lugar de childNodes o firstChild cuando solo interesa trabajar con elementos HTML.

La comprensión de esta estructura jerárquica y los diferentes tipos de nodos es fundamental para manipular eficientemente el DOM y crear interacciones dinámicas en las páginas web.

El objeto document: Punto de entrada y métodos globales para interactuar con la página

El objeto document representa el punto de entrada principal al árbol DOM y proporciona la interfaz fundamental para interactuar con el contenido de una página web. Este objeto es una instancia de la interfaz Document y está disponible globalmente en cualquier script que se ejecute en un navegador.

Acceso al objeto document

El objeto document está disponible de forma inmediata en el contexto de ejecución de JavaScript en el navegador, sin necesidad de inicializarlo:

// El objeto document ya está disponible
console.log(typeof document); // "object"
console.log(document.constructor.name); // "HTMLDocument"

Propiedades fundamentales del document

El objeto document proporciona varias propiedades esenciales que ofrecen acceso directo a elementos clave del documento:

// Acceso a elementos estructurales principales
const htmlElement = document.documentElement; // Elemento <html>
const headElement = document.head; // Elemento <head>
const bodyElement = document.body; // Elemento <body>
const doctype = document.doctype; // Doctype del documento
const title = document.title; // Contenido del elemento <title>

Otras propiedades útiles incluyen:

  • document.URL: La URL completa del documento
  • document.domain: El dominio del documento actual
  • document.referrer: La URL desde la que se navegó a la página actual
  • document.cookie: Las cookies asociadas con el documento
  • document.readyState: El estado de carga del documento (loading, interactive o complete)

Métodos de selección de elementos

El objeto document proporciona métodos poderosos para seleccionar elementos del DOM:

// Métodos de selección básicos
const elementById = document.getElementById('main'); // Selecciona por ID (único)
const elementsByClass = document.getElementsByClassName('item'); // Colección por clase
const elementsByTag = document.getElementsByTagName('div'); // Colección por etiqueta
const elementsByName = document.getElementsByName('username'); // Colección por atributo name

Los métodos modernos basados en selectores CSS ofrecen mayor flexibilidad:

// Métodos de selección con selectores CSS
const firstMatch = document.querySelector('.container p'); // Primer elemento que coincide
const allMatches = document.querySelectorAll('ul > li'); // NodeList con todas las coincidencias

// Ejemplos de selectores avanzados
const activeElements = document.querySelectorAll('[data-status="active"]');
const oddItems = document.querySelectorAll('li:nth-child(odd)');

Creación y manipulación de elementos

El objeto document proporciona métodos para crear nuevos nodos que luego pueden insertarse en el árbol DOM:

// Creación de elementos
const newDiv = document.createElement('div'); // Crea un elemento <div>
const newText = document.createTextNode('Contenido de texto'); // Crea un nodo de texto
const newComment = document.createComment('Esto es un comentario'); // Crea un comentario

// Creación de fragmentos (contenedores ligeros)
const fragment = document.createDocumentFragment();
for (let i = 0; i < 3; i++) {
  const li = document.createElement('li');
  li.textContent = `Item ${i + 1}`;
  fragment.appendChild(li);
}
document.querySelector('ul').appendChild(fragment);

Métodos para escribir en el documento

El objeto document incluye métodos para escribir contenido directamente en el documento:

// Métodos de escritura (usar con precaución)
document.write('<p>Contenido generado dinámicamente</p>');
document.writeln('Texto con salto de línea');

Nota: Los métodos write() y writeln() son considerados obsoletos para muchos casos de uso modernos, ya que pueden sobrescribir todo el documento si se llaman después de que la página ha terminado de cargarse.

Gestión de eventos a nivel de documento

El objeto document permite registrar manejadores de eventos para interacciones a nivel de documento:

// Eventos del ciclo de vida del documento
document.addEventListener('DOMContentLoaded', () => {
  console.log('DOM completamente cargado y analizado');
});

// Eventos de interacción del usuario a nivel de documento
document.addEventListener('click', (event) => {
  console.log('Click en coordenadas:', event.clientX, event.clientY);
});

document.addEventListener('keydown', (event) => {
  console.log('Tecla presionada:', event.key);
});

El evento DOMContentLoaded es particularmente importante ya que se dispara cuando el HTML ha sido completamente cargado y analizado, sin esperar a que terminen de cargar hojas de estilo, imágenes y subframes.

Propiedades y métodos para trabajar con formularios

El objeto document proporciona acceso directo a los formularios del documento:

// Acceso a formularios
const allForms = document.forms; // HTMLCollection de todos los formularios
const formById = document.forms.formId; // Acceso por ID
const formByIndex = document.forms[0]; // Acceso por índice

// Acceso a elementos de formulario
const inputElement = document.forms.loginForm.username;

Métodos para trabajar con cookies

El objeto document permite gestionar cookies a través de su propiedad cookie:

// Establecer una cookie
document.cookie = "username=john; expires=Fri, 31 Dec 2023 23:59:59 GMT; path=/";

// Leer todas las cookies (devuelve un string con todas las cookies)
const allCookies = document.cookie;

// Función para obtener una cookie específica
function getCookie(name) {
  const cookieArr = document.cookie.split(';');
  for (let cookie of cookieArr) {
    const [cookieName, cookieValue] = cookie.trim().split('=');
    if (cookieName === name) {
      return cookieValue;
    }
  }
  return null;
}

Métodos para trabajar con la estructura del documento

El objeto document proporciona métodos para importar y adoptar nodos entre documentos:

// Importar un nodo desde otro documento
const importedNode = document.importNode(externalNode, true); // true para importar descendientes

// Adoptar un nodo de otro documento
const adoptedNode = document.adoptNode(externalNode);

Propiedades relacionadas con el estado de carga

El objeto document proporciona información sobre el estado de carga de la página:

// Comprobar si el DOM está listo
if (document.readyState === 'loading') {
  console.log('El documento está cargando');
} else {
  console.log('El documento ha terminado de cargar');
}

// Escuchar cambios en el estado de carga
document.addEventListener('readystatechange', () => {
  console.log('Estado del documento:', document.readyState);
});

Métodos para trabajar con la selección de texto

El objeto document permite gestionar la selección de texto en la página:

// Obtener la selección actual
const selection = document.getSelection();
console.log('Texto seleccionado:', selection.toString());

// Crear un rango
const range = document.createRange();
const paragraph = document.querySelector('p');
range.selectNodeContents(paragraph); // Selecciona todo el contenido del párrafo

// Aplicar un rango a la selección
selection.removeAllRanges();
selection.addRange(range);

El objeto document es el núcleo de la interacción con el DOM, proporcionando los métodos y propiedades fundamentales que permiten a JavaScript manipular dinámicamente el contenido, estructura y comportamiento de una página web.

CONSTRUYE TU CARRERA EN IA Y PROGRAMACIÓN SOFTWARE

Accede a +1000 lecciones y cursos con certificado. Mejora tu portfolio con certificados de superación para tu CV.

30 % DE DESCUENTO

Plan mensual

19.00 /mes

13.30 € /mes

Precio normal mensual: 19 €
63 % DE DESCUENTO

Plan anual

10.00 /mes

7.00 € /mes

Ahorras 144 € al año
Precio normal anual: 120 €
Aprende JavaScript online

Ejercicios de esta lección Introducción al DOM

Evalúa tus conocimientos de esta lección Introducción al DOM con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Funciones flecha

JavaScript
Puzzle

Polimorfismo

JavaScript
Test

Array

JavaScript
Código

Transformación con map()

JavaScript
Test

Gestor de tareas con JavaScript

JavaScript
Proyecto

Manipulación DOM

JavaScript
Test

Funciones

JavaScript
Test

Funciones flecha

JavaScript
Código

Async / Await

JavaScript
Código

Creación y uso de variables

JavaScript
Test

Excepciones

JavaScript
Puzzle

Promises

JavaScript
Código

Funciones cierre (closure)

JavaScript
Test

Herencia

JavaScript
Puzzle

Herencia

JavaScript
Test

Estructuras de control

JavaScript
Código

Selección de elementos DOM

JavaScript
Test

Modificación de elementos DOM

JavaScript
Test

Filtrado con filter() y find()

JavaScript
Test

Funciones cierre (closure)

JavaScript
Puzzle

Funciones

JavaScript
Puzzle

Mapas con Map

JavaScript
Test

Reducción con reduce()

JavaScript
Test

Callbacks

JavaScript
Puzzle

Manipulación DOM

JavaScript
Puzzle

Promises

JavaScript
Test

Async / Await

JavaScript
Test

Eventos del DOM

JavaScript
Puzzle

Async / Await

JavaScript
Puzzle

Promises

JavaScript
Puzzle

Filtrado con filter() y find()

JavaScript
Código

Callbacks

JavaScript
Test

Creación de clases y objetos Restaurante

JavaScript
Código

Reducción con reduce()

JavaScript
Código

Filtrado con filter() y find()

JavaScript
Puzzle

Reducción con reduce()

JavaScript
Puzzle

Conjuntos con Set

JavaScript
Puzzle

Herencia de clases

JavaScript
Código

Eventos del DOM

JavaScript
Test

Clases y objetos

JavaScript
Puzzle

Modificación de elementos DOM

JavaScript
Puzzle

Mapas con Map

JavaScript
Puzzle

Introducción a JavaScript

JavaScript
Test

Funciones

JavaScript
Código

Tipos de datos

JavaScript
Test

Clases y objetos

JavaScript
Test

Array

JavaScript
Test

Conjuntos con Set

JavaScript
Test

Array

JavaScript
Puzzle

Encapsulación

JavaScript
Puzzle

Clases y objetos

JavaScript
Código

Uso de operadores

JavaScript
Puzzle

Uso de operadores

JavaScript
Test

Estructuras de control

JavaScript
Test

Excepciones

JavaScript
Test

Transformación con map()

JavaScript
Puzzle

Funciones flecha

JavaScript
Test

Selección de elementos DOM

JavaScript
Puzzle

Encapsulación

JavaScript
Test

Mapas con Map

JavaScript
Código

Creación y uso de variables

JavaScript
Puzzle

Polimorfismo

JavaScript
Puzzle

Tipos de datos

JavaScript
Puzzle

Estructuras de control

JavaScript
Puzzle

Todas las lecciones de JavaScript

Accede a todas las lecciones de JavaScript y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a JavaScript y certifícate

Certificados de superación de JavaScript

Supera todos los ejercicios de programación del curso de JavaScript y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  1. Comprender la estructura y funciones del Document Object Model (DOM).
  2. Aprender a acceder y modificar elementos HTML usando JavaScript.
  3. Conocer la jerarquía y tipos de nodos en el DOM.
  4. Optimizar las manipulaciones del DOM para mejorar el rendimiento.
  5. Identificar los estándares y versiones del DOM soportados por navegadores.