Document Object Model (DOM)

<< Browser Object Model Eventos >>

El Document Object Model es una estructura interna en árbol que contiene una representación de todos los nodos del HTML incluyendo sus atributos (objetos). Podemos navegar a través de esta jerarquía, añadiendo, eliminando, o modificando nodos y con ello la estructura del documento HTML de forma dinámica.

Tumba de Internet Explorer

El objeto principal del DOM es document. Este es un objeto global del lenguaje. Cada nodo HTML contenido dentro del documento es un objeto de tipo Element, y cada uno de estos elementos contiene a su vez otros nodos, atributos y estilo.

Navegando por el DOM

Los siguientes métodos nos permiten acceder a los diferentes nodos del DOM. Muchos de ellos, además de usarlos desde document, también se pueden usar desde cualquier elemento HTML que tengamos referenciado en el código.

document.documentElement → Representa el elemento <html>

document.head → Representa el elemento <head>

document.body → Representa el elemento <body>

document.getElementById("id") → Devuelve el elemento que tiene el id especificado, o null si no existe.

document.getElementsByClassName("class") → Devuelve un array de elementos que tengan la clase CSS especificada. Al llamar a este método desde otro nodo distinto de document, buscará los elementos a partir de dicho nodo.

document.getElementsByTagName("HTML tag") → Devuelve un array con los elementos con la etiqueta HTML especificada (Por ejemplo "p" → párrafos), que estén dentro del nodo referenciado.

element.firstElementChild o element.lastElementChild → Devuelve el primer (o último) elemento HTML contenido (hijo) en el nodo actual. También existen las propiedades firstChild y lastChild. La diferencia es que estas últimas tienen en cuenta cualquier tipo de nodo, incluyendo texto y comentarios.

element.children → Devuelve una colección con todos los elementos HTML que contiene el nodo referenciado. La colección no es de tipo Array sino HTMLCollection, que es similar, pero más limitada. También podemos utilizar element.childNodes, pero en este caso nos devolverá también los nodos de texto y comentarios como parte de la colección.

element.parentNode → Devuelve el nodo padre de un elemento.

element.nextElementSibling → Devuelve el siguiente nodo del mismo nivel (el hermano). El método previousElementSibling devuelve el anterior. Estas propiedades solo tienen en cuenta nodos del tipo HTML. También tenemos las propiedades nextSibling o previousSibling que tienen en cuenta el texto y los comentarios.

Query Selector

Además de los métodos vistos anteriormente para obtener elementos del DOM, existen unos más avanzados que utilizan selectores CSS para devolver los elementos HTML que cumplan ciertas características. Estos métodos se pueden llamar desde document, o desde cualquier nodo HTML del DOM.

document.querySelector("selector") → Devuelve el primer elemento que coincide con el selector.

document.querySelectorAll("selector") → Devuelve una colección con todos los elementos que coinciden con el selector.

element.closest("selector") → Navega hacia arriba por el árbol del DOM hasta encontrar un nodo antecesor del actual que cumpla con el selector.

Ejemplo usando querySelector() y querySelectorAll():

Manipulando el DOM

Vamos a ver algunos métodos que nos permiten eliminar, añadir o reemplazar elementos del DOM.

document.createElement("tag") → Crea un elemento HTML. Todavía no estará en el DOM, hasta que lo insertemos (usando appendChild, por ejemplo) dentro de otro elemento del DOM.

document.createTextNode("text") → Crea un nodo de texto que podemos introducir dentro de un elemento HTML. También podríamos usar innerText en su lugar, pero esto nos permite por ejemplo, añadir un nodo de texto junto a otros nodos HTML dentro de un mismo elemento fácilmente.

element.append(...childElements) → Añade uno o más elementos al final del nodo actual. También pueden ser nodos de texto simplemente pasándole como parámetro un string.

element.prepend(...childElements) → Añade uno o más elmentos al principio del nodo actual.

element.before(...childElements) → Añade uno o más elementos antes del elemento actual (hermanos).

element.after(...childElements) → Añade uno o más elementos después del elemento actual (hermanos).

element.remove() → El elemento se elimina del DOM.

element.replaceWith(...otherElements) → Reemplaza el elemento actual por uno o más elementos que se sitúan en la misma posición.

element.replaceChildren(...otherElements) → Reemplaza todos los hijos del elemento actual por los elementos que se le pasan por parámetro. Si no se le pasa ninguno, el elemento queda vacío.

Existen otros métodos como appendChild, insertBefore, removeChild o replaceChild que no vale la pena explicar debido a que los métodos arriba descritos son más modernos, más fáciles de utilizar, y permiten hacer más cosas con menos código.

Atributos

Dentro de los elementos HTML, y dependiendo del tipo de elemento, hay atributos estándar como name, id, href, src, etc. Se puede acceder a estos atributos directamente como propiedades del objeto para leerlos o modificarlos (ejemplo: elemento.href = "http://dominio.com").

Otras propiedades y métodos útiles para trabajar con los atributos son:

element.attributes → Devuelve el array con los atributos de un elemento

element.className → Se usa para acceder (leer o cambiar) al atributo class. Otros atributos a los que se puede acceder directamente son: element.id, element.title, element.style (propiedades CSS), … .

element.classList → Array de clases CSS del elemento. A diferencia de className, que es una cadena con las clases separadas por espacio, este atributo te las devuelve en forma de array o lista. Tiene métodos muy útiles para consultar y modificar clases como:
  classList.contains("clase"): true si tiene la clase.
  classList.replace("clase1","clase2"): Quita la clase "clase1" y la sustituye por la clase "clase2".
  classList.add("clase1"): Añade la clase "clase1" al elemento.
  classList.remove("clase1"): Le quita la clase "clase1".
  classList.toggle("clase1"): Si no tiene "clase1", la añade. En caso contrario, la quita.

element.hasAttribute("attrName") → Devuelve cierto si el elemento tiene un atributo con el nombre especificado.

element.getAttribute("attrName") → Devuelve el valor del atributo.

element.setAttribute("attrName", "newValue") → Cambia el valor del atributo.

El atributo style

El atributo style permite modificar las propiedades CSS asociadas a un elemento. La propiedad CSS a modificar deben escribirse con el formato camelCase, mientras que en CSS se emplea en el formato snake-case. Por ejemplo, al atributo background-color (CSS), se accede a partir de element.style.backgroundColor. El valor establecido a una propiedad será un string que contendrá un valor CSS válido para el atributo.