Advertisement
  1. Web Design
  2. UX/UI
  3. Navigation

Cómo conservar el estado del menú al cargar la página (usando almacenamiento local)

Scroll to top
Read Time: 7 min

() translation by (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

En este tutorial, crearemos un sitio estático simple con Tailwind CSS y luego aprenderemos cómo conservar el estado de su menú al cargar la página.

La primera vez que visitemos el sitio, el menú estará oculto. Sin embargo, tan pronto como lo abramos y cerremos el navegador, utilizaremos almacenamiento local y JavaScript para mantener el menú abierto la próxima vez que visitemos el sitio. De hecho, permanecerá abierto hasta que lo volvamos a cerrar.

¿Estás listo para otro desafío?

1. Crea el proyecto

Como primer paso, tenemos que configurar la estructura del proyecto y decidir dónde lo alojaremos.

Una opción es desarrollarlo de manera local y después, una vez que esté listo, subirlo a GitHub Pages. He utilizado este método anteriormente para diferentes demostraciones. Por ejemplo, échale un vistazo a esta donde se personaliza las pestañas de Bootstrap 4.

Un método alternativo es usar CodePen Projects tanto para el desarrollo como para el alojamiento. Cabe señalar que, según tu plan de CodePen, podrás alojar una cantidad diferente de proyectos.

Para este tutorial, como no lo hemos hecho antes, vamos a crear un proyecto en CodePen y vamos a aprovechar todas las potentes funciones que lo acompañan.

How to create a CodePen ProjectHow to create a CodePen ProjectHow to create a CodePen Project

De manera predeterminada, CodePen ofrece varias plantillas de proyectos iniciales. Aquí, seleccionaremos la más básica.

The selected starter template for our CodePen ProjectThe selected starter template for our CodePen ProjectThe selected starter template for our CodePen Project

Nuestro proyecto incluirá cuatro archivos HTML similares, un archivo SCSS que se compilará en un CSS y un archivo JavaScript, como este:

The project structureThe project structureThe project structure

Y por último, aunque no por ello menos importante, podrás exportarlo y ejecutarlo desde tu máquina local.

You can export a CodePen ProjectYou can export a CodePen ProjectYou can export a CodePen Project

2. Tailwind CSS

En vez de crear los estilos desde cero, vamos a usar Tailwind CSS, un nuevo y popular framework de CSS con un enfoque «utility-first» y que ha ganado mucho terreno con los desarrolladores. Fue creado por Adam Wathan, su filosofía es mover toda la complejidad a los archivos HTML añadiendo clases preexistentes a los elementos.

Tailwind CSS frameworkTailwind CSS frameworkTailwind CSS framework

Como siempre me gustó este concepto, lo he seguido en el pasado para algunas demostraciones como esta. Aprende más aquí:

3. El HTML

Todos los archivos HTML contendrán una cabecera y algo de contenido ficticio.

Dentro de la cabecera colocaremos:

  • El logotipo de la empresa
  • El ícono de hamburguesa
  • El menú de navegación

También necesitaremos incluir los siguientes archivos:

  • El archivo de CSS Tailwind
  • Nuestros propios archivos de CSS y JavaScript

Para hacer que el ícono de hamburguesa sea un poco más accesible, usaremos los atributos ARIA: aria-label, aria-extended y aria-controls. Como veremos más adelante, los valores de los dos primeros atributos cambiarán según el estado del menú.

Este es el marcado para la página index.html:

1
<!DOCTYPE html>
2
<html lang="en">
3
  <head>
4
    <!-- Meta -->
5
    <meta charset="UTF-8">
6
    <title>Home Page</title>
7
    <meta name="viewport" content="width=device-width, initial-scale=1">
8
9
    <!-- Styles -->
10
    <link rel="stylesheet" href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css">
11
    <link rel="stylesheet" href="styles/index.processed.css">
12
  </head>
13
14
  <body class="text-lg">
15
    <header class="sticky top-0 bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 p-5 shadow-xl">
16
      <nav>
17
        <div class="flex items-center justify-between">
18
          <a href="index.html">
19
            <img width="178" height="38" src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/162656/horizontal-logo.svg" alt="forecastr logo">
20
          </a>
21
          <button class="toggle-button grid gap-y-2.5 focus:outline-none" type="button" aria-controls="menu" aria-label="Open navigation" aria-expanded="false">
22
            <span class="bg-white w-10 h-1 transition-transform"></span>
23
            <span class="bg-white w-10 h-1"></span>
24
            <span class="bg-white w-10 h-1 transition-transform"></span>
25
          </button>
26
        </div>
27
        <div class="absolute right-0 top-full mt-4 mr-3 overflow-y-hidden">
28
          <ul id="menu" class="menu flex transition-transform transform translate-y-full">
29
            <li class="mr-6">
30
              <a href="about.html" class="inline-block font-semibold text-gray-400 hover:text-gray-900 transition-colors duration-300 p-2">About</a>
31
            </li>
32
            <li class="mr-6">
33
              <a href="clients.html" class="inline-block font-semibold text-gray-400 hover:text-gray-900 transition-colors duration-300 p-2">Clients</a>
34
            </li>
35
            <li>
36
              <a href="contact.html" class="inline-block font-semibold text-gray-400 hover:text-gray-900 transition-colors duration-300 p-2">Contact</a>
37
            </li>
38
          </ul>
39
        </div>
40
      </nav>
41
    </header>
42
43
    <main class="my-20">
44
      <section>
45
        <div class="container max-w-5xl px-8 mx-auto">
46
          <h1 class="font-bold text-5xl mb-8">Home Page</h1>
47
          <p class="mb-5"...</p>
48
          ...
49
          <a href="" class="inline-block bg-red-500 hover:bg-red-600 text-white font-semibold py-2 px-4 rounded-lg shadow-md" target="_blank">Read article</a>
50
        </div>
51
      </section>
52
      <!-- more sections here -->
53
    </main>
54
55
    <!-- Scripts -->
56
    <script src="scripts/index.js"></script>
57
  </body>
58
</html>

No te sientas abrumado por la cantidad de clases auxiliares de CSS. Todas estas provienen de Tailwind CSS (además de toggle-button y menu que usaremos en la parte de JavaScript para hacer referencia a los elementos objetivo).

Como este no es un tutorial sobre Tailwind, no voy a explicar lo que hace cada clase. La mayoría de ellas se explican por sí mismas, pero hay otras como text-5xl que no son tan claras, por lo que tendrás que buscar en la documentación o en la consola del navegador y ver su uso exacto.

Solo para darte una idea, considera las clases que aplicamos al elemento .menu junto con el CSS generado:

Clase de utilidad CSS generado
flex display: flex;
transition-transform
transition-property: transform;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms
transform
--tw-translate-x: 0;
--tw-translate-y: 0;
--tw-rotate: 0;
--tw-skew-x: 0;
--tw-skew-y: 0;
--tw-scale-x: 1;
--tw-scale-y: 1;
transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
translate-y-full --tw-translate-y: 100%;

4. Alternar el menú

Cada vez que hagamos clic en el enlace del menú, ocurrirán las siguientes acciones:

  • Cambiaremos su clase is-active. Si contiene esta clase, se tranformará suavemente en un ícono menos.
  • Cambiaremos la clase translate-y-full del menú. Esta es una clase de Tailwind que determinará si el menú aparecerá o no.
  • Dependiendo del estado del menú, actualizaremos los atributos aria-label y aria-expanded de ARIA.

Este es el código JavaScript que implementará esta funcionalidad:

1
const toggleButton = document.querySelector(".toggle-button");
2
const menu = document.querySelector(".menu");
3
const activeClass = "is-active";
4
const hiddenClass = "translate-y-full";
5
6
toggleButton.addEventListener("click", function() {
7
  this.classList.toggle(activeClass);
8
  menu.classList.toggle(hiddenClass);
9
  if (menu.classList.contains(hiddenClass)) {
10
    this.setAttribute("aria-label", "Open navigation");
11
    this.setAttribute("aria-expanded", "false");
12
  } else {
13
    this.setAttribute("aria-label", "Close navigation");
14
    this.setAttribute("aria-expanded", "true");
15
  }
16
});

Y los estilos SCSS relacionados:

1
.toggle-button {
2
  &.is-active {
3
    span {
4
      &:first-child {
5
        transform: translateY(14px);
6
      }
7
8
      &:last-child {
9
        transform: translateY(-14px);
10
      }
11
    }
12
  }
13
}

Conservar el estado del menú al cargar la página

Hasta el momento, nuestro menú funciona muy bien. Pero vayamos un paso más allá y aprendamos cómo preservar su estado. Dicho lo cual, la primera vez que visitemos el sitio, el menú será invisible. Sin embargo, tan pronto como lo abramos y cerremos el navegador, este permanecerá abierto la próxima vez que visitemos el sitio hasta que lo volvamos a cerrar.

Este es un caso perfecto para mostrar cómo el almacenamiento local puede resolver este tipo de solicitud.

Seamos más específicos:

  • Tras hacer clic en el ícono de hamburguesa, guardaremos en el almacenamiento local la clave menu-state. Los valores posibles pueden ser open y closed.
Store the menu state in local storageStore the menu state in local storageStore the menu state in local storage
  • Cuando la página se cargue, comprobaremos el valor de esta clave. Si el usuario ya ha abierto el menú, el ícono de hamburguesa recibirá la clase is-active, el menú no contendrá la clase translate-y-full y los atributos relacionados con ARIA cambiarán en consecuencia.
The open state of the menuThe open state of the menuThe open state of the menu

Veamos el código JavaScript que controlará esta lógica:

1
...
2
3
if (localStorage.getItem("menu-state") === "open") {
4
  toggleButton.classList.add(activeClass);
5
  menu.classList.remove(hiddenClass);
6
  toggleButton.setAttribute("aria-label", "Close navigation");
7
  toggleButton.setAttribute("aria-expanded", "true");
8
}
9
10
toggleButton.addEventListener("click", function() {
11
  if (menu.classList.contains(hiddenClass)) {
12
    localStorage.setItem("menu-state", "closed");
13
  } else {
14
    localStorage.setItem("menu-state", "open");
15
  }
16
});

Naturalmente, como mejora, puedes evitar que las animaciones se ejecuten al cargar la página. Pero dejaré esto por ahora, ya que su importancia es secundaria.

¡Has aprendido cómo usar el almacenamiento local!

¡Hemos terminado, amigos! Hoy, aprendimos a crear un proyecto de CodePen utilizando Tailwind CSS para sus estilos y manteniendo el estado de su menú al cargar la página con JavaScript y almacenamiento local. Espero que hayas aprendido una o dos cosas nuevas y que pronto puedas aplicarlas en tus proyectos.

No dudes en mejorar la demostración haciendo que el menú sea aún más accesible o añadiendo más funciones de Tailwind. De ser así, ¡no olvides compartirlo con nosotros!

Como Tailwind es un tema de moda en este momento, planeo escribir un tutorial orientado a Tailwind que describirá cómo personalizar sus opciones predeterminadas o combinarlo con otro framework popular como Bootstrap. Si quieres algo específico como esto, háznoslo saber a través de las redes sociales.

¡Como siempre, gracias por leer!

Más proyectos de JavaScript prácticos

Tenemos bastantes tutoriales interesantes de JavaScript que te ayudarán a aprender. ¡Adelante!

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.