Trabajar con consultas de medios JavaScript
¿Qué es lo primero que te viene a la mente cuando piensas en consultas de medios? Quizás algo en un archivo CSS parecido a esto:
body { background-color: plum;}
@media (min-width: 768px) { body { background-color: tomato; }}
Las consultas de medios CSS son un ingrediente central en cualquier diseño responsivo. Son una excelente manera de aplicar diferentes estilos a diferentes contextos, ya sea en función del tamaño de la ventana gráfica, la preferencia de movimiento, la combinación de colores preferida, interacciones específicas e incluso ciertos dispositivos como impresoras, televisores y proyectores, entre muchos otros.
¿Pero sabías que también tenemos consultas de medios para JavaScript? ¡Es cierto! Puede que no los veamos con tanta frecuencia en JavaScript, pero definitivamente hay casos de uso que he encontrado útiles a lo largo de los años para crear complementos responsivos, como controles deslizantes. Por ejemplo, con una resolución determinada, es posible que necesite volver a dibujar y recalcular los elementos del control deslizante.
Trabajar con consultas de medios en JavaScript es muy diferente a trabajar con ellas en CSS, aunque los conceptos son similares: cumplir algunas condiciones y aplicar algunas cosas.
Usando matchMedia()
Para determinar si el documento coincide con la cadena de consulta de medios en JavaScript, utilizamos el matchMedia()
método. Aunque es oficialmente parte de la especificación del módulo de vista del modelo de objetos CSS, que se encuentra en estado de borrador de trabajo, la compatibilidad del navegador es excelente, ya que se remonta a Internet Explorer 10 con una cobertura global del 98,6%.
Estos datos de soporte del navegador son de Caniuse, que tiene más detalles. Un número indica que el navegador admite la función en esa versión y superiores.
Escritorio
Cromo | Firefox | ES DECIR | Borde | Safari |
---|---|---|---|---|
9 | 6 | 10 | 12 | 5.1 |
Móvil/Tableta
androidcromo | Android Firefox | Androide | Safari en iOS |
---|---|---|---|
125 | 126 | 3 | 5.0-5.1 |
El uso es casi idéntico al de las consultas de medios CSS. Pasamos la cadena de consulta de medios a matchMedia(
) y luego verificamos la .matches
propiedad.
// Define the queryconst mediaQuery = window.matchMedia('(min-width: 768px)')
La consulta de medios definida devolverá un MediaQueryList
objeto. Es un objeto que almacena información sobre la consulta de medios y la propiedad clave que necesitamos es .matches
. Se trata de una propiedad booleana de sólo lectura que regresa true
si el documento coincide con la consulta de medios.
// Create a media condition that targets viewports at least 768px wideconst mediaQuery = window.matchMedia('(min-width: 768px)')// Check if the media query is trueif (mediaQuery.matches) { // Then trigger an alert alert('Media Query Matched!')}
Ese es el uso básico para hacer coincidir las condiciones de los medios en JavaScript. Creamos una condición de coincidencia ( matchMedia()
) que devuelve un objeto ( MediaQueryList
), lo comparamos ( .matches
) y luego hacemos cosas si la condición se evalúa como verdadera. ¡No totalmente diferente a CSS!
Pero hay más. Por ejemplo, si cambiáramos el tamaño de la ventana por debajo de nuestro tamaño de ventana de destino, nada se actualizará como lo hará con CSS desde el primer momento. Esto se debe a que .matches
es perfecto para verificaciones instantáneas únicas, pero no puede verificar cambios continuamente. Eso significa que necesitamos…
Escuche los cambios
MediaQueryList tiene un método addListener()
(y el subsiguiente ) que acepta una función de devolución de llamada (representada por el evento) que se invoca cuando cambia el estado de la consulta de medios. En otras palabras, podemos activar funciones adicionales cuando las condiciones cambian, lo que nos permite "responder" a las condiciones actualizadas.removeListener()
.onchange
// Create a condition that targets viewports at least 768px wideconst mediaQuery = window.matchMedia('(min-width: 768px)')
function handleTabletChange(e) { // Check if the media query is true if (e.matches) { // Then log the following message to the console console.log('Media Query Matched!') }}
// Register event listenermediaQuery.addListener(handleTabletChange)// Initial checkhandleTabletChange(mediaQuery)
El doble golpe de matchMedia()
y MediaQueryList
nos brinda el mismo poder no solo para igualar las condiciones de los medios que proporciona CSS, sino también para responder activamente a las condiciones actualizadas.
Cuando registra un detector de eventos, addListener()
no se activará inicialmente. Necesitamos llamar a la función del controlador de eventos manualmente y pasar la consulta de medios como argumento.
La vieja forma de hacer las cosas.
En aras del contexto (y un poco de nostalgia), me gustaría cubrir la forma antigua, pero aún popular, de realizar "consultas de medios" en JavaScript (y, sí, esas citas son importantes aquí). El enfoque más común es vincular un resize
detector de eventos que verifique window.innerWidth
o window.innerHeight
.
Todavía verás algo como esto en la naturaleza:
function checkMediaQuery() { // If the inner width of the window is greater then 768px if (window.innerWidth 768) { // Then log this message to the console console.log('Media Query Matched!') }}
// Add a listener for when the window resizeswindow.addEventListener('resize', checkMediaQuery);
Dado que el evento de cambio de tamaño se llama en cada cambio de tamaño del navegador, ¡esta es una operación costosa! Al observar el impacto en el rendimiento de una página vacía, podemos ver la diferencia.
Una forma aún más sencilla de ver la diferencia es con la ayuda de un registro de consola.
Incluso si miramos más allá de los problemas de rendimiento, el cambio de tamaño es restrictivo en el sentido de que no nos permite escribir consultas de medios avanzadas para aspectos como la impresión y la orientación. Entonces, si bien imita el comportamiento de “consulta de medios” al permitirnos igualar los anchos de las ventanas gráficas, es incapaz de igualar mucho de cualquier otra cosa, y sabemos que las verdaderas consultas de medios son capaces de hacer mucho más.
Conclusión
¡Ese es un vistazo a las consultas de medios en JavaScript! Exploramos cómo matchMedia()
nos permite definir las condiciones de los medios y examinamos el MediaQueryList
objeto que nos permite realizar comprobaciones únicas ( .matches
) y persistentes ( addListener()
) de esas condiciones para que podamos responder a los cambios ( .onchange
) invocando funciones.
También vimos la forma “antigua” de hacer las cosas escuchando los resize
eventos en la ventana. Si bien todavía se usa ampliamente y es una forma totalmente legítima de responder a los cambios en el tamaño del archivo window.innerWidth
, no puede realizar comprobaciones de las condiciones avanzadas de los medios.
Para finalizar el artículo, aquí hay un ejemplo útil que no se puede lograr a la antigua usanza. Usando una consulta de medios verificaré si el usuario está en modo horizontal. Este enfoque es común cuando se desarrollan juegos HTML5 y se ve mejor en un dispositivo móvil.
Deja un comentario