APIs de HTML

En la introducción de esta serie, se dice que “los elementos HTML son los nodos que forman el Modelo de objetos del documento”. Ya hablamos sobre el tipo de nodos de elementos. En esta sección, analizamos las APIs de elementos que permiten consultar esos nodos.

El DOM y el AOM

El DOM es una API para acceder a documentos y manipularlos. El DOM es el árbol de todos los nodos del documento. Algunos nodos pueden tener elementos secundarios, mientras que otros no. El árbol incluye elementos, junto con sus atributos y nodos de texto.

Árbol de nodos de MLW que muestra elementos y nodos de texto.

Las herramientas del navegador no proporcionan visualizaciones de árbol como la anterior, pero puedes ver los nodos en el inspector de elementos.

El DOM/ARIA

La representación del árbol que se puede inspeccionar en las herramientas para desarrolladores del navegador es el árbol de accesibilidad. El AOM se basa en el DOM. Del mismo modo, el árbol de accesibilidad contiene objetos que representan todos los elementos de marcado, atributos y nodos de texto:

Ejemplo de AOM

APIs de elementos HTML

La letra del medio de DOM es “o”. Al igual que el ejemplo de objeto person o car de la mayoría de las clases introductorias a la programación orientada a objetos, cada nodo del árbol de documentos es un objeto que se puede manipular con JavaScript.

El navegador proporciona varias APIs que ofrecen métodos, eventos y consultas y actualizaciones de propiedades compatibles de forma nativa. Los nodos de elementos contienen información sobre todos los atributos establecidos en el elemento. Puedes usar interfaces HTML para acceder a información sobre los atributos de un elemento. Por ejemplo, podemos usar HTMLImageElement.alt para obtener los atributos alt de todas las imágenes:

let allImages = document.querySelectorAll('img');
allImages.forEach((imageInstance) => {
  console.log(imageInstance.alt);
});

Las interfaces HTML proporcionan más que solo acceso a los atributos de un elemento; puedes acceder a mucha más información. Podemos encontrar el elemento HTMLElement.offsetHeight de solo lectura para obtener la altura de cada sección de nuestra página en relación con el diseño.

let allSections = document.querySelectorAll('section');
allSections.forEach((sectionInstance) => {
  console.log(sectionInstance.offsetHeight);
});

Si el usuario cambia la orientación del dispositivo o cambia el ancho del viewport, la altura de cada <section> cambiará y las propiedades del DOM se actualizarán automáticamente con ella.

Las APIs de la interfaz HTML no se limitan a acceder a los valores de los atributos. El DOM proporciona estadísticas sobre el estado actual de la IU. Las APIs de HTML pueden acceder a toda esa información. Puedes acceder a la duración de un video, a la posición de una vista en la reproducción actual y a si el video (o el audio) terminó de reproducirse con HTMLMediaElement.duration, HTMLMediaElement.currentTime y HTMLMediaElement.ended, respectivamente.

Interfaces de elementos disponibles

La mayoría de los elementos HTML que hemos visto hasta ahora en esta serie y que aún no hemos visto, además de algunos elementos de sección, tienen una interfaz de DOM asociada. La interfaz base de todos los elementos se llama Element. HTMLElement hereda de Element y todas las interfaces específicas del elemento HTML heredan de él. Algunas interfaces específicas de elementos se implementan con varios elementos similares.

Las interfaces incluyen lo siguiente:

La convención de nombres es “HTML”, seguida de un elemento o una agrupación de elementos en mayúsculas, seguida de “Elemento”, pero la parte del elemento o la agrupación de elementos no sigue un patrón exacto. No te preocupes. No es necesario que los memorices. Solo es importante saber que existen para que puedas buscarlas cuando lo necesites.

Si tienes una colección de elementos, también hay algunas interfaces de colección. Por ejemplo, el método HTMLCollection.namedItem() muestra el primer elemento de la colección cuyo atributo id o name coincide con el parámetro, o nulo si no hay ningún elemento que coincida.

Más de 30 elementos no tienen una interfaz de DOM asociada que no sea HTMLElement, incluidos <address>, <article>, <section>, <nav>, <header>, <footer>, <aside> y <hgroup>. Muchos elementos que no admiten atributos no obsoletos ni globales tienen interfaces específicas del elemento, como HTMLPElement (el elemento <p>) y HTMLUnknownElement (<😃> o cualquier otro elemento que no esté definido), pero esas interfaces no implementan propiedades ni métodos adicionales además de las propiedades y métodos heredados de HTMLElement, y no se mencionan anteriormente.

Métodos y propiedades redundantes de la API

Si una interfaz tiene el mismo método o nombre de propiedad que una interfaz que hereda, el método o la propiedad de herencia reemplazan al heredado. En otras palabras, los métodos y las propiedades superiores anulan los secundarios. Cuando accedimos a las propiedades alt y offsetHeight en las APIs de elementos HTML con imageInstance.alt y sectionInstance.offsetHeight, respectivamente, el código no identificó a qué API se estaba accediendo. Por lo general, como en estos dos ejemplos, esto no es un problema.

Sin embargo, hay algunos casos en los que la redundancia puede causar un problema. Por ejemplo, HTMLCollection.length es de solo lectura, mientras que la interfaz de herencia, HTMLOptionsCollection, tiene una propiedad de longitud (que solo muestra la propiedad options de <select>) con acceso de lectura y escritura. HTMLOptionsCollection se puede usar para establecer el tamaño de la colección.

Otras interfaces

Hay interfaces adicionales que permiten manipular las ubicaciones de las ramas de los nodos del DOM. Las interfaces Node y Window heredan la interfaz EventTarget, que nos proporciona addEventListener() y removeEventListener(). A su vez, las interfaces de Element, Document y DocumentFragment (que vimos en elementos personalizados) heredan de Node, y la interfaz de HTMLElement hereda de Element.

La interfaz de node

Cada tipo de nodo DOM está representado por una interfaz basada en Node, que proporciona información y métodos a medida que los elementos se relacionan con el árbol DOM. La interfaz Node permite consultar y agregar nodos al árbol de nodos.

La famosa función "recorrer el DOM" de Douglas Crockford usa firstChild de Node y las propiedades nextSibling.

const walk_the_DOM = function walk(node, callback) {
  callback(node);
  node = node.firstChild;
  while (node) {
    walk(node, callback);
    node = node.nextSibling;
  }
};

Usamos los métodos appendChild() y cloneNode() de Node para definir elementos personalizados. La interfaz de Node proporciona muchas propiedades y métodos útiles para consultar y manipular el DOM.

customElements.define('star-rating',
  class extends HTMLElement {
    constructor() {
      super(); // Always call super first in constructor
      const starRating = document.getElementById('star-rating-template').content;
      const shadowRoot = this.attachShadow({
        mode: 'open'
      });
      shadowRoot.appendChild(starRating.cloneNode(true));
    }
  });

El método attachShadow() es un método de la interfaz de Element. También hay una interfaz shadowRoot para la API de Shadow DOM que se renderiza por separado del árbol del DOM principal de un documento.

Las interfaces Document y HTMLDocument

La interfaz Document hereda de Node. Representa la página web cargada en el navegador, ya sea que el documento sea HTML, SVG, XML, MathML o algún otro. La interfaz Document también hereda de la interfaz HTMLDocument.

document permite un acceso rápido a los tipos de nodos y la capacidad de crear colecciones de tipos de elementos específicos, como document.body y document.styleSheets. HTMLDocument permite acceder a información relevante para el documento que no se encuentra en los nodos HTML, como Document.location, Document.lastModified y Document.Cookie.

Hay varias APIs disponibles según las funciones que se muestran a través de la interfaz del documento, como la API de arrastrar y soltar y la API de FullScreen. Ambos heredan de Element.

La interfaz de Window

La interfaz de Window incluye elementos disponibles a nivel global más allá del DOM que se pueden usar para manipularlo. Window proporciona funciones, espacios de nombres, objetos y constructores documentados en JavaScript y Referencias del DOM de MDN.

La interfaz Window es la API del objeto que contiene el documento. El objeto window global es la ventana en la que se ejecuta la secuencia de comandos. Cada pestaña del navegador contiene su propio objeto Window. La interfaz de Window puede consultar el contenido de la pestaña, así como la ventana y el dispositivo en general. Por ejemplo, el método resizeTo() se puede usar para cambiar el tamaño de la ventana del navegador, y la propiedad devicePixelRatio proporciona acceso a los píxeles de la pantalla del dispositivo. Cuando accedes a la información de la pestaña en la que se encuentra el contenido en lugar del árbol DOM que muestra la pestaña, es probable que la ventana sea la interfaz que buscas.

Hay varias APIs disponibles según las funciones que se muestran a través de la interfaz de Window, incluidas las APIs de Web Workers y IndexedDB.

Verifica tu comprensión

Pon a prueba tus conocimientos sobre las APIs de HTML.

¿Qué significa la O en DOM?

Orientada.
Vuelve a intentarlo.
Objetos.
Correcto.
Exterior
Vuelve a intentarlo.

¿Qué interfaz puede ayudarte a obtener información sobre la pestaña en la que se encuentra el contenido?

Ventana
Correcto.
Documento
Vuelve a intentarlo.
Nodo
Vuelve a intentarlo.