Saltar al contenido principal

Client Side Scripting

  • Usar o enviar JS al cliente
  • Ejemplo con LocalStorage

Notas

  1. Para acceder a los datos, como user_id, username, etc. se pueden crear data-atributes
  2. Obtener el elemento con el ID, ej. btn-add
  3. Extraer los data-atributes, estos vienen en el dataset
  4. Si se utilizan los ViewTransitions el JS solo se ejecuta una vez aunque se navegue entre páginas. Se ejecuta otra vez si se hace reload. Para evitar eso, se envuelve el script o función en un evento especial de los ViewTransitions. No es necesario si no se utilizan las ViewTransitions
<button id="btn-favorite" data-name={name} data-id={id}>
<Icon name="heart-outline" data-outline size={50} />
<Icon name="heart-fill" data-full size={50} class="hidden" />
</button>

<script>
  interface FavoritePokemon {
    name: string;
    id: number;
  }

  // Sin view transitions no seria necesario envolver el código en el listener
  const handlePageLoad = () => {
    // Obtener los pokemons favoritos del localStorage
    let favoritePokemons: FavoritePokemon[] = JSON.parse(
      localStorage.getItem("favoritePokemons") ?? "[]"
    );

    const btnFavorite = document.getElementById(
      "btn-favorite"
    ) as HTMLButtonElement;
    if (!btnFavorite) return;

    // Datos del botón
    const name = btnFavorite.dataset.name ?? "";
    const id = btnFavorite.dataset.id ?? "";
    // Datos de los internos del botón
    const heartOutline = btnFavorite.querySelector(
      "[data-outline]"
    ) as HTMLElement;
    const heartFill = btnFavorite.querySelector("[data-full]") as HTMLElement;

    // Mostar el corazón lleno si el pokemon está en favoritos
    const isFavorite = favoritePokemons.some(
      (pokemon) => pokemon.name === name
    );
    if (isFavorite) {
      heartOutline.classList.add("hidden");
      heartFill.classList.remove("hidden");
    }

    // Guardar o eliminar el pokemon de favoritos
    const toggleFavorite = () => {
      // Verificar si el pokemon ya está en favoritos
      // Some es un método que verifica si al menos un elemento cumple con la condición
      const isFavorite = favoritePokemons.some(
        (pokemon) => pokemon.name === name
      );

      if (isFavorite) {
        // Si el pokemon ya está en favoritos, se elimina
        favoritePokemons = favoritePokemons.filter(
          (pokemon) => pokemon.name !== name
        );
      } else {
        // Si el pokemon no está en favoritos, se agrega
        favoritePokemons.push({ id: +id, name: name });
      }
     
      // Guardar en localStorage
      localStorage.setItem(
        "favoritePokemons",
        JSON.stringify(favoritePokemons)
      );
    };

    btnFavorite.addEventListener("click", () => {
      heartOutline.classList.toggle("hidden");
      heartFill.classList.toggle("hidden");
      toggleFavorite();
    });
  };

  // Para ejecutar código cuando la página se ha cargado
  // Util cuando se utilizan las view transitions
  // Sin esto, el código solo se ejecutaría una vez
  document.addEventListener("astro:page-load", handlePageLoad);
</script>

ViewTransitions Lifecycle

Eventos especiales del ViewTransition

EventoDescripción
astro:after-preparation
astro:after-swapDespués de hacer la preparación, antes del load
astro:before-preparationAntes de iniciar el cambio, cuando el usuario hace clic
astro:before-swapAntes de hacer el cambio
astro:page-loadCuando se ha navegado a la nueva pantalla, se ejecuta dos veces