Cómo hacer un botón de desplazamiento hacia arriba discreto
Un botón para volver al principio de la página permite al usuario volver rápidamente al principio de la página sin hacer demasiado esfuerzo. Esto puede resultar muy útil cuando la página tiene mucho contenido o sucede, por ejemplo, en sitios web de una sola página, cuando se utiliza el desplazamiento infinito, o en dispositivos móviles donde diferentes tamaños de pantalla pueden hacer que el contenido se extienda.
Esos botones generalmente flotan en la esquina inferior de los sitios y luego lo llevan de regreso a la parte superior de la página cuando se hace clic en ellos. Son bastante fáciles de crear con JavaScript. Pero visualmente, buscamos que no sea molesto y al mismo tiempo sea un objetivo lo suficientemente grande como para tocarlo o hacer clic. Veamos algunas formas en que podemos hacer esto, comenzando de manera simple y luego mejorando las cosas a medida que avanzamos.
Opción 1: hazlo simple
Primero, seleccionamos el botón en JavaScript.
var scrollToTopBtn = document.getElementById("scrollToTopBtn")
Ahora document.documentElement
devuelve el elemento raíz del documento. Lo necesitamos para obtener los valores de compensación. Entonces, a continuación, guardémoslo en una llamada variable rootElement
; de esa manera es más fácil llamar el código.
var rootElement = document.documentElement
Agregaremos un detector de eventos de clic al botón:
function scrollToTop { // scroll to top logic}scrollToTopBtn.addEventListener("click", scrollToTop)
Luego, dentro de la scrollToTop
función, haremos que se desplace hasta la parte superior de la pantalla con el scrollTo
método.
function scrollToTop() { // Scroll to top logic rootElement.scrollTo({ top: 0, behavior: "smooth" })}
También podemos darle estilo al botón un poco:
#scrollToTopBtn { background-color: black; border: none; border-radius: 50%; color: white; cursor: pointer; font-size: 16px; line-height: 48px; width: 48px;}
Ahora podemos colocar el botón en algún lugar de la página, por ejemplo, en el pie de página:
footer !-- Scroll to top button -- button☝️/button/footer
Y obtenemos esto:
Opción 2: detectar la posición de desplazamiento
Podemos detectar el desplazamiento con un detector de eventos de desplazamiento.
function handleScroll() { // Do something on scroll}document.addEventListener("scroll", handleScroll)
La handleScroll
función se llamará cada vez que el usuario se desplace. Ahora necesitamos la cantidad total de píxeles que podemos desplazar.
scrollHeight
da la altura de un elemento, incluida la parte no visible debido al desbordamiento.clientHeight
da la altura interior de un elemento en píxeles, que es la altura de la parte visible.
Si restamos scrollHeight
por clientHeight
, obtenemos la cantidad total de píxeles que podemos desplazar:
var scrollTotal = rootElement.scrollHeight - rootElement.clientHeight
Ahora tenemos una llamada variable scrollTotal
que representa el número máximo de píxeles que se pueden desplazar verticalmente. Al dividir la cantidad desplazada por la cantidad total de píxeles que podemos desplazar, obtenemos una proporción entre 0 y 1. Jugando con esta proporción, podemos activar y desactivar fácilmente el botón.
Por ejemplo, agregaremos una condición que muestre el botón de desplazamiento hacia arriba cuando el usuario se haya desplazado un 80% (o una proporción de 0,80) hacia abajo en la altura total de la página. El 80% es un número arbitrario. Básicamente, cuanto más nos acerquemos a 1, más tendrá que desplazarse el usuario antes de ver el botón.
Aquí está el JavaScript:
var rootElement = document.documentElement
function handleScroll() { // Do something on scroll var scrollTotal = rootElement.scrollHeight - rootElement.clientHeight if ((rootElement.scrollTop / scrollTotal ) 0.80 ) { // Show button scrollToTopBtn.classList.add("showBtn") } else { // Hide button scrollToTopBtn.classList.remove("showBtn") }}
document.addEventListener("scroll", handleScroll)
Querremos algo de CSS para colocar el botón correctamente cuando aparezca:
.scrollToTopBtn { /* same general styles as before */ /* place it at the bottom-right corner */ position: fixed; bottom: 30px; right: 30px;
/* keep it at the top of everything else */ z-index: 100;
/* hide with opacity */ opacity: 0;
/* also add a translate effect */ transform: translateY(100px);
/* and a transition */ transition: all .5s ease}
.showBtn { opacity: 1; transform: translateY(0)}
Con eso, el botón aparece cuando el usuario baja un 80% de la página y luego se oculta cuando está por encima de eso.
Esto parece una gran opción, y configurar un detector de eventos para que lo haga es bastante fácil. Pero la sobrecarga de rendimiento puede ser costosa ya que siempre estamos comprobando la posición de desplazamiento actual.
Hay otra opción que se encarga de esto…
Opción 3: Observador de intersección
La API de Intersection Observer es una excelente solución al problema anterior. Es una API de navegador bastante reciente que permite a los desarrolladores traspasar la mayoría de estas tareas al navegador, de una manera más optimizada. Travis Almand escribió una explicación detallada de cómo funciona. Así es como lo define MDN:
La API Intersection Observer proporciona una forma de observar de forma asincrónica los cambios para la intersección de un elemento de destino con un elemento ancestro o con la ventana gráfica de un documento de nivel superior.
¡Con buena pinta! Eso significa que el botón puede ser nuestro elemento objetivo:
// We select the element we want to targetvar target = document.querySelector("footer");
Luego escribimos una función de devolución de llamada que hace algo cuando nuestro elemento se “interseca” con la ventana gráfica, que es una forma elegante de decir cuándo aparece a la vista.
Y una vez que el pie de página entra o sale de la ventana gráfica, todo lo que realmente queremos hacer es agregar o eliminar una clase. La devolución de llamada recibe una serie de entradas como parámetro.
function callback(entries, observer) { // The callback will return an array of entries, even if you are only observing a single item entries.forEach(entry = { if (entry.isIntersecting) { // Show button scrollToTopBtn.classList.add('showBtn') } else { // Hide button scrollToTopBtn.classList.remove('showBtn') } });}
Necesitamos crear una nueva IntersectionObserver
instancia y pasarle la función de devolución de llamada que acabamos de escribir.
let observer = new IntersectionObserver(callback);
Finalmente, le decimos al observador que comienza a observar (err, observar) el elemento objetivo que se seleccionó arriba para cuando se cruza con la ventana gráfica:
observer.observe(target);
¿Y qué pasa con el desplazamiento suave?
¡Por supuesto que es posible! De hecho, Chris nos mostró cómo se puede hacer con CSS en 2019:
html body !-- the entire document -- a href="#top"Jump to top of page/a /body/html
html { scroll-behavior: smooth;}
Hay un poco más de matices, como mejoras de accesibilidad que Chris también cubre en la publicación. El punto es que CSS está adquiriendo nuevos poderes que pueden lograr cosas para las que solíamos usar JavaScript.
¡Ahí tienes! Empezamos con una idea bastante simple. Lo mejoramos mostrando y ocultando el botón según la posición de desplazamiento del usuario. Luego mejoramos el rendimiento implementando la API Intersection Observer en lugar de observar la posición de desplazamiento actual. Y, finalmente, vimos cómo se puede utilizar CSS para un desplazamiento fluido. En conjunto, obtenemos un botón de desplazamiento hacia arriba que es fácil de ver y usar, sin bloquear otros elementos de la página.
Deja un comentario