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ícateConceptos 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
osrc
.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.
Navegación por el árbol DOM
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 comogetElementsByClassName()
. 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 documentodocument.domain
: El dominio del documento actualdocument.referrer
: La URL desde la que se navegó a la página actualdocument.cookie
: Las cookies asociadas con el documentodocument.readyState
: El estado de carga del documento (loading
,interactive
ocomplete
)
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()
ywriteln()
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.
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
Polimorfismo
Array
Transformación con map()
Gestor de tareas con JavaScript
Manipulación DOM
Funciones
Funciones flecha
Async / Await
Creación y uso de variables
Excepciones
Promises
Funciones cierre (closure)
Herencia
Herencia
Estructuras de control
Selección de elementos DOM
Modificación de elementos DOM
Filtrado con filter() y find()
Funciones cierre (closure)
Funciones
Mapas con Map
Reducción con reduce()
Callbacks
Manipulación DOM
Promises
Async / Await
Eventos del DOM
Async / Await
Promises
Filtrado con filter() y find()
Callbacks
Creación de clases y objetos Restaurante
Reducción con reduce()
Filtrado con filter() y find()
Reducción con reduce()
Conjuntos con Set
Herencia de clases
Eventos del DOM
Clases y objetos
Modificación de elementos DOM
Mapas con Map
Introducción a JavaScript
Funciones
Tipos de datos
Clases y objetos
Array
Conjuntos con Set
Array
Encapsulación
Clases y objetos
Uso de operadores
Uso de operadores
Estructuras de control
Excepciones
Transformación con map()
Funciones flecha
Selección de elementos DOM
Encapsulación
Mapas con Map
Creación y uso de variables
Polimorfismo
Tipos de datos
Estructuras de control
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.
Introducción A Javascript
Introducción Y Entorno
Tipos De Datos
Sintaxis
Variables
Sintaxis
Operadores
Sintaxis
Estructuras De Control
Sintaxis
Funciones
Sintaxis
Funciones Cierre (Closure)
Sintaxis
Arrays Y Métodos
Estructuras De Datos
Conjuntos Con Set
Estructuras De Datos
Mapas Con Map
Estructuras De Datos
Funciones Flecha
Programación Funcional
Filtrado Con Filter() Y Find()
Programación Funcional
Transformación Con Map()
Programación Funcional
Reducción Con Reduce()
Programación Funcional
Clases Y Objetos
Programación Orientada A Objetos
Excepciones
Programación Orientada A Objetos
Encapsulación
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Manipulación Dom
Dom
Selección De Elementos Dom
Dom
Modificación De Elementos Dom
Dom
Eventos Del Dom
Dom
Callbacks
Programación Asíncrona
Promises
Programación Asíncrona
Async / Await
Programación Asíncrona
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
- Comprender la estructura y funciones del Document Object Model (DOM).
- Aprender a acceder y modificar elementos HTML usando JavaScript.
- Conocer la jerarquía y tipos de nodos en el DOM.
- Optimizar las manipulaciones del DOM para mejorar el rendimiento.
- Identificar los estándares y versiones del DOM soportados por navegadores.