Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Dúvida] Como adicionar vários Event Listeners dinamicamente usando javascript puro?

Ainda com a pokédex do último tópico, eu estou tentando fazer a mesma coisa que eu fiz no evento inline (exemplificado no snippet abaixo), só que com um event listener.

let offset = 0;
const limit = 10;

function loadPokemonItems(offset, limit) {
  pokeApi.getPokemons(offset, limit).then((pokemons = []) => {
    const pokemonItems = pokemons
      .map((pokemon) => {
        return `
        <a
            href="pokemon-profile.html"
            onclick="setPokemonProfile(
                          '${pokemon.number}'
                          , '${pokemon.name}'
                          ,'${pokemon.image}'
                          , '${pokemon.types}'
                        )
                    "
        >
        <li class="pokemon ${pokemon.type}">
          <span class="number">#${pokemon.number}</span>
          <span class="name">${pokemon.name}</span>
          <div class="detail">
            <ul class="types">
              ${pokemon.types
                .map(
                  (type) => `
              <li class="type ${type}">${type}</li>
              `
                )
                .join("")}
            </ul>
            <img src="${pokemon.image}" alt="${pokemon.name}" />
          </div></li
      ></a>
      `;
      })
      .join("");

    pokemonList.innerHTML += pokemonItems;
  });
}

loadPokemonItems(offset, limit);

Mas por algum motivo eu só consigo pegar os dados do primeiro item do array (no caso, o Bulbassauro):

let offset = 0;
const limit = 10;

function loadPokemonItems(offset, limit) {
  pokeApi
    .getPokemons(offset, limit)
    .then((pokemons = []) => {
      const pokemonItems = pokemons
        .map((pokemon) => {
          return `
        <a href="pokemon-profile.html">
        <li class="pokemon ${pokemon.type}">
          <span class="number">#${pokemon.number}</span>
          <span class="name">${pokemon.name}</span>
          <div class="detail">
            <ul class="types">
              ${pokemon.types
                .map(
                  (type) => `
              <li class="type ${type}">${type}</li>
              `
                )
                .join("")}
            </ul>
            <img src="${pokemon.image}" alt="${pokemon.name}" />
          </div></li
      ></a>
      `;
        })
        .join("");

      pokemonList.innerHTML += pokemonItems;
      return pokemons;
    })
    .then((pokemons = []) => {
      const links = Array.from(document.getElementsByTagName("a"));
      links.forEach((link) =>
        link.addEventListener("click", () =>
          pokemons.forEach((pokemon) => {
            setPokemonProfile(
              pokemon.number,
              pokemon.name,
              pokemon.image,
              pokemon.types
            )
          }
          )
        )
      );
    });
}

loadPokemonItems(offset, limit);

Printscreen com a tela inicial da pokédex, mostrando todos os primeiros 10 pokémon, incluindo nosso Bulbassauro.Função setPokemonProfile:

const setPokemonProfile = (number, name, image, stringTypes) => {
  const iterableTypes = stringTypes.split(",")
  const pokemon = { number, name, image, iterableTypes };
  sessionStorage.setItem("pokemon", JSON.stringify(pokemon));
};

Alguém consegue me ajudar a atribuir o event listener para todos os itens? https://github.com/kellysondias/pokedex-dio/blob/event-listener/assets/js/index.js

1 resposta
solução!

Olá, Kellyson, como você está?

Seu projeto está ficando muito legal, parabéns :)

O erro que você está enfrentando está acontecendo porque você está adicionando o Event Listener para cada link, mas no callback do evento, você está percorrendo todos os Pokémons e definindo o perfil para cada um deles. Isso faz com que o perfil seja definido para o último Pokémon da lista em cada clique. A referência a pokemon dentro do event listener não está capturando corretamente os valores individuais de cada Pokémon durante a iteração.

Uma solução para isso seria associar cada Pokémon ao seu respectivo link no momento da criação do link. Assim, cada link teria um Event Listener que define o perfil para o Pokémon correspondente.

Para adicionar um evento de clique a vários itens de uma lista de Pokémon, primeiro, localize esses itens, depois percorra cada um e adicione um listener de clique individual a eles. Dentro desse listener, execute uma ação específica (como mostrar detalhes do Pokémon) garantindo que os dados corretos sejam usados para essa ação. Finalmente, teste o código para garantir que todos os itens da lista respondam adequadamente ao clique do usuário, permitindo que cada um deles tenha um comportamento personalizado quando clicado.

Espero que dê tudo certo ;)

Abraços!