Geometría del modelo de objetos de documento (DOM): introducción y guía para principiantes
Las soluciones de interfaz de usuario, como el desplazamiento infinito, la animación de elementos en el desplazamiento o incluso el popular arrastrar y soltar, son soluciones de interfaz interesantes que existen desde hace algún tiempo. En esta guía, Pearl Akpan analiza los métodos y propiedades que hacen que estas interfaces sean realizables, por qué es relevante comprender estos métodos y propiedades y, luego, profundiza en algunos casos de uso práctico para ellos.
Si ha estado trabajando con JavaScript por un tiempo, es posible que esté bastante familiarizado con las secuencias de comandos DOM (Document Object Model) y CSSOM (CSS Object Model) . Más allá de las interfaces definidas por las especificaciones DOM y CSSOM, se especifica un subconjunto de métodos y propiedades en el módulo de vista CSSOM, que proporciona una API para determinar y manipular la geometría del elemento DOM para representar interfaces de usuario interesantes en la web.
Requisitos previos:
- Un repaso sobre el sistema de coordenadas;
- Comprensión del diseño y posicionamiento de CSS;
- Escribir devoluciones de llamada en JavaScript;
- Un poco de paciencia.
Tabla de contenido:
- El módulo de vista CSSOM
- ¿Por qué son importantes los métodos y propiedades de la geometría?
- Geometría del nodo del elemento
- Geometría de ventanas y documentos
- Coordenadas
- Casos de uso
El módulo de vista CSSOM
El modelo de objetos CSS (CSSOM) es un conjunto de API que permiten la manipulación de CSS desde JavaScript. Así como DOM proporciona la interfaz para manipular HTML, CSSOM permite a los autores leer y manipular CSS.
CSSOM View es un módulo de CSS que contiene un montón de propiedades y métodos, todos agrupados para proporcionar a los autores una interfaz separada para obtener información sobre la vista visual de los elementos. Las propiedades de este módulo son predominantemente de solo lectura y se calculan cada vez que se accede a ellas: valores en vivo.
Actualmente, el módulo de vista CSSOM es solo un borrador de trabajo y está bajo revisión en la Tabla de especificaciones del W3C . Su esencia, por lo tanto, es definir estas interfaces, tanto las ya existentes como las nuevas, de manera que puedan ser compatibles entre navegadores.
¿Por qué son importantes los métodos y propiedades de la geometría?
Desde mi punto de vista, existen algunas razones para intentar comprender y utilizar las propiedades y métodos de la vista CSSOM.
En primer lugar, no es que la interfaz de usuario cotidiana requiera componentes móviles para lograr las historias de usuario más básicas. A menos que esté creando una interfaz de juego, es posible que no siempre necesite hacer que las cosas se muevan en su sitio web. Las propiedades geométricas son útiles a pesar de esto porque la capacidad de manipular mediante programación la vista visual de los elementos DOM brinda a los desarrolladores más superpoderes para implementar interfaces de usuario dinámicas.
Los tableros Kanban se implementan porque los componentes se pueden arrastrar y soltar en las secciones relevantes. Se carga más contenido a medida que los usuarios se desplazan hasta la parte inferior de un documento porque los valores de posición de desplazamiento son legibles. Entonces, si bien puede no parecer inmediatamente obvio, estas características se pueden lograr conociendo la información precisa sobre el tamaño y la posición de los elementos.
En segundo lugar, al visualizar documentos HTML en un navegador web, los elementos DOM se representan en formas visuales, por lo que tienen una representación visual correspondiente que los navegadores pueden ver/visualizar. Acceder a las propiedades visuales en vivo de estos elementos DOM a través de las propiedades y métodos de vista CSSOM brinda una ventaja sobre las propiedades CSS normales. Y luego preguntas cómo:
- Después de configurar las propiedades de ancho y alto de los elementos HTML en CSS, la propiedad de tamaño del cuadro de CSS finalmente establece cómo se calculan el ancho y el alto total de un elemento. Esto crea un JavaScript propenso a errores si el valor de nuestro tamaño de caja cambia.
- En segundo lugar, casi no hay forma de leer un valor numérico exacto del ancho de un elemento configurado en automático. Y a veces necesitamos el ancho en píxeles y tamaños exactos.
Finalmente, parece mucho más flexible y útil tener un conjunto de valores de vida de solo lectura en los que se pueda confiar al escribir algún otro código que manipule los elementos en función de los valores de vida actuales.
Geometría del nodo del elemento
Compensaciones
Las coordenadas especificadas utilizando el modelo de "desplazamiento" utilizan la esquina superior izquierda del elemento que se examina o en el que ha ocurrido un evento.
—MDN
A diferencia de otras propiedades en la Vista CSSOM, las propiedades de desplazamiento solo están disponibles para HTMLElement
los nodos derivados del nodo Elemento. Como tal, no puede leer las propiedades de compensación de an SVGElement
porque no existen.
Desplazamiento hacia la izquierda y hacia arriba
Utiliza las propiedades de solo lectura offsetLeft
y offsetTop
proporciona las coordenadas x
/ y
de un elemento en relación con su offsetParent
. La offsetLeft
propiedad devuelve la distancia del borde exterior izquierdo del elemento actual en relación con el borde interior izquierdo de offsetParent
mientras que la offsetTop
propiedad devuelve la distancia del borde superior exterior del elemento actual en relación con el borde superior interior de offsetParent
.
Padre compensado
El offsetParent
de cualquier elemento es su elemento ancestro más cercano que tiene una propiedad de posición CSS que no es estática, un elemento td
, th
o table
en la base, el body
elemento.
Ancho y alto de compensación
Estas propiedades de solo lectura proporcionan el tamaño exterior completo de los nodos de elementos. Se offsetWidth
determina calculando el tamaño total de los bordes verticales, el relleno y el contenido de un elemento, incluidas las barras de desplazamiento que puedan existir. Se offsetHeight
calcula de la misma manera utilizando los bordes horizontales, el relleno y la altura del contenido de un elemento.
Clientela
Cliente izquierda y superior
En el sentido más básico, estas propiedades de solo lectura dan el tamaño en píxeles del ancho del borde izquierdo y el ancho del borde superior de un elemento, respectivamente. Sin embargo, en un sentido más profundo, el valor de las propiedades clientLeft
y clientTop
de un elemento proporciona las coordenadas relativas del lado interior (relleno exterior) de ese elemento desde su lado exterior (borde exterior).
Entonces, cuando un documento tiene una dirección de escritura de derecha a izquierda y barras de desplazamiento verticales a la izquierda, devolverá clientLeft
valores de coordenadas, incluido el tamaño de la barra de desplazamiento. Esto se debe a que la barra de desplazamiento se muestra entre el lado interior (relleno exterior) de ese elemento y su lado exterior (borde exterior).
Ancho y alto del cliente
Las propiedades de solo lectura clientWidth
y clientHeight
de un elemento devuelven el tamaño del área dentro de los bordes del elemento. La clientWidth
propiedad devolverá el tamaño del ancho del contenido de un elemento y su relleno vertical sin la barra de desplazamiento. Si no hay relleno, entonces clientWidth
es solo el tamaño del ancho del contenido de ese elemento. Esto es lo mismo para la clientHeight
propiedad, que devolverá el tamaño de la altura del contenido de un elemento más el relleno horizontal y, en ausencia de cualquier relleno, devolverá solo la altura del contenido como clientHeight
.
Pergaminos
Desplazarse hacia la izquierda y hacia arriba
Un elemento sin contenido desbordante en su x
eje o y
eje regresará 0
cuando se consulten sus propiedades scrollLeft
y , respectivamente. scrollTop
La propiedad de un elemento scrollLeft
devuelve la distancia en píxeles a la que se desplaza horizontalmente el contenido de un elemento, mientras que la scrollTop
propiedad proporciona la distancia en píxeles a la que se desplaza verticalmente el contenido de un elemento.
Los píxeles devueltos por las propiedades scrollLeft
y scrollTop
de un elemento no siempre se pueden ver en la ventana gráfica desplazable o en el área del cliente debido al desplazamiento. Se puede considerar que los píxeles representan el tamaño del área que se ha desplazado hacia la izquierda o hacia arriba.
Las propiedades scrollLeft
y scrollTop
son propiedades de lectura y escritura, por lo que sus valores se pueden manipular.
Nota : Es posible que las propiedades scrollLeft
y scrollTop
no siempre devuelvan números enteros y pueden devolver valores de punto flotante.
Ancho y alto del desplazamiento
La scrollWidth
propiedad de un elemento calcula su contenido clientWidth
más todo el contenido desbordante en su lado izquierdo y derecho, mientras que la scrollHeight
propiedad calcula el contenido desbordante completo de un elemento clientHeight
en los lados superior e inferior del elemento.
Es por eso que si un elemento no tiene contenido desbordante en sus ejes x
o y
, sus propiedades scrollWidth
y scrollHeight
devolverán los mismos valores, respectivamente, que sus propiedades clientWidth
y clientHeight
.
MDN explica los valores de propiedad scrollWidth
y scrollHeight
como:
"... Igual al ancho o alto mínimo que requeriría el elemento para ajustar todo el contenido en la ventana gráfica sin usar una barra de desplazamiento horizontal o vertical".
Geometría de ventanas y documentos
La
Window
interfaz representa una ventana que contiene un documento DOM; ladocument
propiedad apunta al documento DOM cargado en esa ventana.
Las propiedades geométricas del documento cargado en la ventana y la ventana misma son relevantes por varias razones. A veces necesitamos leer el ancho de toda la ventana gráfica y la altura completa de nuestro documento, otras veces, incluso queremos desplazar una página hasta cierto punto definido y todo eso. Bueno, por supuesto, las propiedades para leer la información y los valores relevantes no quedan fuera del módulo de vista CSSOM.
Debido a que hay un html
elemento raíz (etiquetado como Document.documentElement
en el DOM) que define todo el documento HTML, también podemos obtener las diversas propiedades de alto, ancho y posición del documento HTML consultando el elemento raíz.
Ancho y alto de la ventana
Las propiedades para calcular el ancho y el alto de la ventana se dividen en propiedades de ancho y alto interior y exterior. Para calcular el ancho y alto exterior de la ventana, se utilizan las propiedades outerWidth
de solo lectura y, que devuelven respectivamente el ancho y el alto de toda la ventana del navegador.outerHeight
Para obtener el ancho y alto interior de la ventana, se utilizan las propiedades innerWidth
y . innerHeight
Lo que se devuelve es el ancho y el alto (incluidas las barras de desplazamiento) de toda la ventana gráfica donde el documento es visible.
Es posible que necesite obtener el ancho o alto de la ventana gráfica interna de la ventana sin la barra de desplazamiento ni los bordes y, en tales casos, use o clientWidth
en clientHeight
, Document.documentElement
que es el elemento raíz que representa el documento.
Ancho y alto del documento
Nunca establecemos bordes, relleno o valores de margen en el propio elemento raíz. Aún así, en los elementos contenidos en el Documento, el uso de las propiedades scrollWidth
y scrollHeight
en el elemento raíz Document.documentElement
devolverá todo el ancho y alto del documento.
Valores de desplazamiento de ventanas y documentos
Desplazarse hacia la izquierda y hacia arriba
Como se explora en la sección Geometría del nodo del elemento , las propiedades scrollLeft
y scrollTop
devuelven en píxeles el tamaño del área desplazada hacia la izquierda o hacia arriba de un elemento.
Por lo tanto, para determinar el estado de desplazamiento hacia la izquierda o hacia arriba de un documento, el uso de las propiedades scrollLeft
y scrollTop
en Document.documentElement
devolverá valores que representan el tamaño de la parte del documento que se ha desplazado y no es visible en la ventana gráfica de la ventana.
Los valores del estado de desplazamiento de un documento se pueden obtener alternativamente y más preferiblemente utilizando los valores window.pageXOffset
y .window.pageYOffset
Métodos de desplazamiento de ventanas y documentos
Podemos desplazar la página mediante programación en respuesta a ciertas interacciones del usuario utilizando métodos de desplazamiento definidos en el módulo de vista CSSOM. Considerémoslos.
Los métodos scroll()yscrollTo()
Estos dos métodos de ventana son básicamente los mismos métodos y le permiten desplazar la página a coordenadas específicas ( x
, y
) en el documento. Los valores de las coordenadas representan una posición absoluta desde las esquinas superior e izquierda del documento.
Para visualizar esto simplemente, ejecutemos este código:
window.scrollTo(0, 500); //Scrolls the page vertically to 500 pixels from the page’s origin (0, 0).window.scrollTo(0, 500);//Page stays at the same point.
Después de ejecutarla window.scrollTo(0, 500)
por primera vez, un intento de ejecutarla por segunda vez no produce ningún efecto porque la página ya se encuentra en una posición absoluta de 500 píxeles desde el origen del documento en su y
eje.
Los métodos scroll()
y scrollTo()
definen parámetros para los argumentos correspondientes que representan el número de píxeles a lo largo de los ejes horizontal y vertical, respectivamente, a los que desea que se desplace la página o un diccionario x
de y
opciones que contiene valores superior, izquierdo y de comportamiento.
El valor del comportamiento determina cómo se produce el desplazamiento. Podría ser "smooth"
, que proporciona un efecto de desplazamiento suave, o "auto"
, que hace que el desplazamiento sea como un salto rápido a las coordenadas especificadas.
El scrollBy()método
Este es un método de desplazamiento relativo. Desplaza la página en relación con su posición actual y no tiene en cuenta el Document
origen en absoluto.
Para examinar este método, usemos el ejemplo de código de la sección de métodos scroll()
y scrollTo()
:
window.scrollTo(0, 500); //Scrolls the page 500 pixels from the current position, say (0, 0), to (0, 500).window.scrollTo(0, 500);//Scrolls the page another 500 pixels from the current position to (0, 1000).
Coordenadas
Los sistemas de coordenadas son la pesadilla de cómo se definen las posiciones de los elementos en los métodos y propiedades de la vista CSSOM.
Al especificar la ubicación de un píxel en un contexto gráfico, su posición se define en relación con un punto fijo en el contexto. Este punto fijo se llama origen. La posición se especifica como el número de píxeles desplazados desde el origen a lo largo de cada dimensión del contexto.
El CSSOM utiliza sistemas de coordenadas estándar, y estos generalmente solo se diferencian en términos de dónde se encuentra su origen.
Coordenadas de ventana y documento
Si bien CSSOM utiliza cuatro sistemas de coordenadas estándar, los sistemas de coordenadas del cliente y de la página son los más utilizados en el módulo de vista CSSOM. Las dimensiones o posiciones de los elementos generalmente se definen en relación con el documento o la ventana gráfica.
Coordenadas del cliente (relativas a la ventana)
No encontré mejor descripción de las coordenadas del cliente que la de MDN:
El sistema de coordenadas "cliente" utiliza como origen la esquina superior izquierda de la ventana gráfica o contexto de navegación en el que ocurrió el evento. Esta es toda el área de visualización en la que se presenta el documento. El desplazamiento no es un factor.
Los valores de las coordenadas del cliente son similares a los utilizados position: fixed
en CSS y se calculan desde el borde superior izquierdo de la ventana gráfica.
Coordenadas de página (relativas al documento)
El sistema de coordenadas de "página" proporciona la posición de un píxel en relación con la esquina superior izquierda del conjunto
Document
en el que se encuentra el píxel. Eso significa que un punto determinado en un elemento dentro del documento mantendrá las mismas coordenadas en el modelo de página a menos que el elemento se mueva (ya sea directamente cambiando su posición o indirectamente agregando o cambiando el tamaño de otro contenido).
Los valores de las coordenadas de la página son similares a los utilizados position: absolute
en CSS y se calculan desde el Document
borde superior izquierdo. La posición relativa a la página de un elemento siempre permanecerá igual independientemente del desplazamiento, mientras que su posición relativa a la ventana dependerá del desplazamiento del documento.
Coordenadas del elemento
El Element.getBoundingClientRect()método
Este método devuelve un objeto llamado DOMRect
objeto cuyas propiedades son las posiciones de píxeles relativas a la ventana y las dimensiones de un elemento. Este es el método al que recurre cuando necesita manipular un elemento relativo a la ventana gráfica.
Debe tener en cuenta que, en determinados casos, el DOMRect
objeto devuelto no siempre contiene los mismos valores de propiedad o dimensiones para el mismo elemento. Esto es específicamente cierto siempre que se agregan transformaciones (inclinar, rotar, escalar) a un elemento.
La razón de esto es bastante lógica:
En el caso de transformaciones,
offsetWidth
yoffsetHeight
devuelve el ancho y alto del diseño del elemento, mientras quegetBoundingClientRect()
devuelve el ancho y alto de representación. Como ejemplo, si el elemento tienewidth: 100px;
ytransform: scale(0.5);
devolverágetBoundingClientRect()
50 como ancho, mientras queoffsetWidth
devolverá 100.
— MDN
Puede visualizar esto haciendo clic en el botón de visualización en este lápiz a continuación:
Consulte el lápiz [DOM Rect Properties [bifurcado]](https://codepen.io/smashingmag/pen/KKedmYx) de Pearl Akpan .
El objeto devuelto por el getBoundingClientRect()
método contiene seis propiedades de dimensión del elemento sobre el que se invocó el método. Estas propiedades son:
x
yy
las propiedades devuelven las coordenadas xey del origen del elemento en relación con la ventana;top
ybottom
las propiedades devuelven las coordenadas y para los bordes superior e inferior del cuadro del elemento;left
yright
las propiedades devuelven coordenadas x para los bordes izquierdo y derecho del cuadro del elemento;height
ywidth
las propiedades devuelven todo el ancho y alto del elemento como si el elemento estuviera configurado enbox-sizing: border-box
.
Coordenadas de eventos del mouse y del puntero
Todos los objetos de evento de mouse o puntero tienen propiedades de coordenadas que definen las coordenadas relativas a la ventana y al documento donde ocurre el evento de mouse o puntero.
Las coordenadas relativas a la ventana para los eventos del mouse se almacenan en las propiedades clientX
y clientY
que denotan las coordenadas x
y y
, respectivamente.
Por otro lado, las coordenadas relativas al documento para los eventos del mouse y del puntero se almacenan en las propiedades pageX
y del objeto del evento pageY
para las coordenadas x
y y
, respectivamente.
Casos de uso
Las API en el módulo de vista CSSOM combinan los métodos y propiedades más básicos pero útiles para acceder a las propiedades geométricas de los elementos DOM tal como se representan en el navegador. Debido a que estas propiedades están activas, son más confiables en casos específicos que sus valores CSS. Pero, ¿cómo se pueden utilizar estas API para crear funciones de interfaz de usuario de la vida real?
Examinaríamos cuatro soluciones de interfaz de usuario cotidianas utilizadas en sitios web y aplicaciones web modernos y cotidianos que se pueden crear utilizando estas API.
En esta sección, nos centraremos únicamente en el código JavaScript para implementar estas soluciones de interfaz de usuario, no en CSS ni HTML.
Componente de desplazamiento hacia arriba
El botón de desplazamiento hacia arriba permite al usuario regresar rápidamente a la parte superior de la página con poco esfuerzo. La API CSSOM View proporciona un método simple para lograr esto con sus métodos scrollTo()
duplicados .scroll()
Aquí hay una implementación del botón de desplazamiento hacia arriba:
Vea el bolígrafo [desplazarse hacia arriba [bifurcado]] (https://codepen.io/smashingmag/pen/VwdvWwK) de Pearl Akpan .
Para lograr esto, necesitamos crear un botón de desplazamiento hacia arriba. En nuestro js
archivo, agregamos un "click"
detector de eventos a este botón:
scrollToTop.addEventListener("click", (e) = { window.scrollTo({left: 0, top: 0, behavior: "smooth"});});
Luego registramos un controlador para este evento que ejecuta (controla) lo que sucede cuando se hace clic en este botón. El código en el controlador de eventos llama al scrollTo()
método de la ventana, con valores que definen la parte superior de la página y el comportamiento del desplazamiento.
Para la experiencia del usuario, definitivamente no serviría de nada ver un botón de desplazamiento hacia la parte superior si un usuario ya está en la parte superior de la página:
document.addEventListener("scroll", (e)= { if(window.pageYOffset = 500) { scrollToTop.style.display = "block"; } else { scrollToTop.style.display = "none"; }});
El código anterior muestra el botón de desplazamiento hacia arriba solo cuando el usuario se ha desplazado cierta distancia utilizando el window.pageYOffset
valor para determinar hasta dónde se ha desplazado la página. Si la página se ha desplazado hasta 500 píxeles hacia la parte superior, el componente de desplazamiento hacia arriba se vuelve visible y, si no, permanece invisible.
Desplazamiento infinito
Con su implementación en las redes sociales populares, el desplazamiento infinito permite a los usuarios desplazarse hacia abajo en una página; Se carga más contenido de forma automática y continua en la parte inferior, eliminando la necesidad del usuario de hacer clic en la página siguiente.
¿Puedes adivinar cómo sabe el navegador cargar más contenido cuando un usuario se desplaza hacia abajo en la página? ¿Cómo se determina cuándo un usuario ha llegado al final?
Sabemos que document.scrollHeight
proporciona la altura total de un documento, document.clientHeight
el tamaño de la pantalla visible o ventana gráfica y/ document.scrollTop
o window.pageYOffset
el tamaño de la parte del documento que se ha desplazado hacia la parte superior. ¿Podríamos hacer una suposición intuitiva de que si document.scrollTop + document.clientHeight = document.scrollHeight
, entonces el usuario ha llegado al final de la página? Creo que sí.
Vea el bolígrafo [Infinite Scroll - [bifurcado]] (https://codepen.io/smashingmag/pen/OJEygVz) de Pearl Akpan .
Este bolígrafo utiliza la técnica de desplazamiento infinito para cargar tarjetas en una página hasta alcanzar su recuento máximo. En su forma más básica, imita cómo los sitios web de comercio electrónico muestran los resultados de búsqueda de productos. Analicemos cómo se logra esto.
Usamos HTML y CSS para definir la forma y el estilo del contenedor de tarjetas y los estilos que card
debe tener cada elemento con la clase. En nuestro bolígrafo, codificamos el primer conjunto de tarjetas con HTML.
Primero, obtenemos y asignamos a las constantes lo siguiente:
- elemento contenedor de tarjetas , que es el elemento principal de todas las tarjetas;
- elemento de estado que muestra el número actual de tarjetas cargadas.
Establecemos un máximo en la cantidad de tarjetas que se deben cargar en la página y también tenemos un valor calculado para la cantidad de tarjetas que se agregarán a la página por carga. Entonces, definimos las constantes a totalCardsNo
y cardLoadAmount
para almacenar los valores para el número máximo de tarjetas y el número de tarjetas que se agregarán:
const cardContainer = document.querySelector("main"); const currentCardStats = document.querySelector(".currentCardNo"); const cardLoadAmount = 9; const totalCardsNo = 90; let lastIndex;
Necesitamos escribir una prueba que verifique cuándo un usuario está en la parte inferior de la página y carga las tarjetas. Según nuestra suposición anterior, si document.scrollTop + document.clientHeight = document.scrollHeight
, entonces nuestro usuario está en la parte inferior de la página.
En nuestro lápiz, agregamos un detector de eventos de desplazamiento a nuestro documento y usamos una función de flecha para manejar el evento de desplazamiento. Esta función "maneja" todas las acciones relacionadas con la carga de tarjetas, pero lo hace sólo cuando el usuario está realmente en la parte inferior de esa página, es decir, la condición document.scrollTop + document.clientHeight = document.scrollHeight
devuelve true
:
document.addEventListener("scroll", (e) = { if (document.documentElement.scrollTop + document.documentElement.clientHeight = document.documentElement.scrollHeight) { const children = cardContainer.children; lastIndex = children.length; } });
Una vez que el usuario está en la parte inferior de la página, inicializamos una constante, children
para contener una HTMLCollection
de todas las tarjetas actualmente c
Deja un comentario