Ir directamente al contenido de esta página

codexexempla.org

El DOM

Tabla de contenidos

  1. Qué es el DOM
  2. Los nodos del árbol
    1. Propiedades generales de los nodos
    2. Identificar el tipo de nodo
    3. Valores y nombres de los nodos
  3. Niveles del DOM

Qué es el DOM

El DOM es una API para XML1, lo que sin siglas quiere decir que es una capa de programación intermedia que representa un documento y que nos permite modificarlo. Por decirlo de otra manera, es una serie de funciones y procedimientos que nos permiten trabajar sobre un modelo abstracto de un documento, que sirve como medio de comunicación entre nuestro lenguaje de programación —en este caso JavaScript— y los contenidos del documento.

El DOM es una interfaz independiente de cualquier lenguaje de programación, pero aquí voy a centrarme en su uso por medio de JavaScript.

Pongamos un ejemplo. Tenemos un documento como el siguiente:


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Título de la página</title>
    </head>
    <body>
        <h1>Encabezado</h1>
        <p>Un párrafo</p>
        <p>Un párrafo con <a href="otra_pagina.htm">un vínculo</a></p>
        <ul>
            <li>Un elemento de lista</li>
            <li>Otro elemento de lista</li>
        </ul>
        <p>Otro párrafo</p>
    </body>
    </html>
            

y por medio de JavaScript queremos modificar la lista. ¿Cómo lo hacemos? Necesitamos que haya alguna manera de indicarle al agente de usuario —por ejemplo, nuestro navegador— que de todos los caracteres que componen ese documento nos interesa seleccionar los que componen el que es un elemento ul. Ahí es donde entra en juego el DOM, que permite que el navegador se represente el documento como un árbol jerárquico, algo así:

El código anterior, representado gráficamente como un árbol jerárquico

Ahora sí, el navegador no interpreta simplemente el documento como una serie de caracteres, sino que «comprende» que existen una serie de elementos con sus propiedades, y que la relación entre todos ellos es una relación estructural. Así, por ejemplo, se puede pedir al navegador que devuelva una lista de los hijos del elemento ul.

Una ventaja de esta interfaz es que la manera de trabajar con ella es análoga a la forma de emplear selectores de CSS basados en el árbol de parentesco que ya vimos.

El modelo resultante del documento original es un árbol, y una vez creado es este árbol lo que representa el navegador, y también lo que modificamos con nuestros scripts.

Los nodos del árbol

Como se ve, el DOM es un modelo jerárquico. En la representación que he ofrecido antes, todo aquello situado en el origen o el final de una rama del árbol es un nodo, y los nodos establecen entre sí relaciones de parentesco. Por ejemplo, el elemento ul es hijo de body, padre de dos li, hermano de h1 y los tres p, descendiente de html y ascendente del texto de cualquiera de los li.

Así, todo documento puede representarse como un conjunto de nodos relacionados entre sí. Además, existe un número limitado de tipos de nodos que son suficientes para representar cualquier documento, y que han sido definidos por el W3C:

Tipos de nodos en el DOM: descripción y posibilidad de tener hijos o no
NodoDescripción¿Hijos?
Document Este nodo es único, y representa el documento en sí.
DocumentType Este nodo también es único, y representa la referencia a la DTD del documento, es decir, la línea del <!DOCTYPE>. No
DocumentFragment Representa un fragmento del modelo total del árbol del documento.
Element Representa un elemento. 2
Attr Representa un atributo de un elemento, en combinación con su valor. No
Text Representa un texto dentro de un elemento, o de una sección CData. No
CDataSection Representa una sección <[!CDATA[]]>. 3
Entity Representa la definición de una entidad en la DTD. No
EntityReference Representa una referencia de entidad. No
ProcessingInstruction Representa una instrucción de proceso. No
Comment Representa un comentario en el código XML. No
Notation Representa una notación definida en la DTD. No

Así, cuando el agente de usuario mapea un documento, lo que hace es asignar a cada nodo una constante que lo identifica. Dependiendo del tipo de nodo, éste aceptará una serie de propiedades y métodos, y podrá tener hijos o no.

Propiedades generales de los nodos

Independientemente del tipo de nodo, hay una serie de propiedades generales que comparten, y que recojo en la tabla siguiente:

Propiedades generales de cualquier nodo
PropiedadDescripciónDevuelve
nodeName El nombre del nodo, que se define dependiendo del tipo de nodo. Una cadena literal
nodeValue El valor del nodo, que se define dependiendo del tipo de nodo. Una cadena literal
nodeType Un número que representa el tipo de nodo del que se trata. Un número del 1 al 12
ownerDocument El documento al que pertenece el nodo. El documento
firstChild El primer hijo del nodo. Un nodo
lastChild El último hijo del nodo. Un nodo
childNodes Una lista de los hijos de un nodo. Una matriz de nodos
previousSibling El hermano anterior al nodo. Un nodo, o null si el nodo es el primer hijo
nextSibling El hermano siguiente al nodo. Un nodo, o null si el nodo es el último hijo
hasChildNodes Indica si el nodo tiene hijos o no. Un booleano
attributes Una lista con los atributos del nodo. Una matriz con los atributos

La sintaxis para acceder a estas propiedades es la misma que vimos para los objetos nativos de JavaScript, por lo que no voy a detenerme a explicarla aquí. No obstante, vamos a emplear muchas de ellas en los ejemplos de las secciones siguientes.

En cuanto a los métodos comunes, les dedico su propia sección: appendChild, insertBefore, replaceChild, removeChild y cloneNode.

Identificar el tipo de nodo

En algún momento podemos necesitar identificar el tipo de un nodo, y para eso contamos con la propiedad nodeType, que devuelve un número. A continuación recojo el tipo de nodo que corresponde a cada número:

Tipos de nodos identificados por el número devuelto por nodeType
Tipo de nodoConstante4Número
Element Node.ELEMENT_NODE 1
Attr Node.ATTRIBUTE_NODE 2
Text Node.TEXT_NODE 3
CDataSection Node.CDATA_SECTION_NODE 4
EntityReference Node.ENTITY_REFERENCE_NODE 5
Entity Node.ENTITY_NODE 6
ProcessingInstruction Node.PROCESSING_INSTRUCTION_NODE 7
Comment Node.COMMENT_NODE 8
Document Node.DOCUMENT_NODE 9
DocumentType Node.DOCUMENT_TYPE_NODE 10
DocumentFragment Node.DOCUMENT_FRAGMENT_NODE 11
Notation Node.NOTATION_NODE 12

Valores y nombres de los nodos

Además, dos de las propiedades listadas anteriormente nos proporcionan datos sobre un nodo: nodeName y nodeValue. Sin embargo, a diferencia de nodeType, su valor no es una constante, sino que dependiendo del tipo de nodo el valor que devuelven difiere:

Resultados de nodeName y nodeValue en relación con el tipo de nodo
Tipo de nodonodeNamenodeValue
Element El nombre del elemento, en mayúsculas null
Attr El nombre del atributo, en minúsculas El valor del atributo como una cadena literal
Text #text El contenido del nodo como una cadena literal
CDataSection #cdata-section El contenido del nodo como una cadena literal
EntityReference El nombre de la entidad de referencia null
Entity El nombre de la entidad null
ProcessingInstruction El nombre del destino de la instrucción El contenido del nodo como una cadena literal
Comment #comment El texto del comentario como una cadena literal
Document #document null
DocumentType El nombre del tipo de documento null
DocumentFragment #document-fragment null
Notation El nombre de la notación null

Con esto, hemos dado el primer paso para conocer el DOM, aunque lo visto no es más que un ápice del nivel más bajo y básico de esta interfaz. No obstante, esta información es necesaria si se quiere trabajar con ella, y avanzar en el estudio de los siguientes niveles.

Niveles del DOM

Dejo fuera de esta sección tanto el DOM 0 como el DHTML5. Si alguien tiene curiosidad, remito a Level 0 DOM (inglés) e Intermediate DOMs (inglés) en quirksmode.org (inglés).

A diferencia de otras recomendaciones como pueda ser la de XHTML 1.0, el DOM no se recoge en un único documento, sino que consiste en tres niveles —a día de hoy—, y cada uno de ellos está a su vez compuesto por varias recomendaciones referidas a distintos aspectos de la interfaz:

Para el nivel 3 del DOM hay muchos más documentos que tratan otros aspectos de esta interfaz (inglés), pero no tienen todavía la categoría de Recomendaciones.

En las siguientes secciones sólo veremos una ínfima parte de lo que contiene la especificación del DOM Core 1.

Notas

  1. Existen otras API para XML, como SAX. Volver
  2. Éste es el único tipo de nodo que puede tener como hijo uno del tipo attr. Volver
  3. Sólo acepta como hijos nodos de tipo Text. Volver
  4. El número devuelto por nodeType es una referencia; estrictamente, al mapear el árbol del documento es una constante la que se asigna a cada nodo para identificarlo. En realidad la mayor parte de las veces para trabajar basta con el número, pero saber algo más no hace daño nunca. Volver
  5. A pesar de que pueda parecerlo, DHTML no es ninguna especificación de un lenguaje, sólo un nombre comercial para englobar las propiedades de los modelos de capas y los métodos con los que operar con ellas en las versiones 4 de Explorer y Netscape. Cosa del pasado, vamos. Volver
  6. Veremos estos conceptos al tratar addEventListener. Volver

Contacto

En virtud de la Ley Orgánica 15/1999 de Protección de Datos de Carácter Personal le informo de que los datos que proporcione no serán empleados para otro fin que el de responder a su mensaje. En especial, me comprometo a no cederlos a terceros ni a emplearlos para enviar información no solicitada.

Del blog de Digital Icon