Как показать информацию по одному персонажу при наведении курсором по pokemon api?

Подскажите пожалуйста как решить данную проблему. С pokemon api мне нужно на странице показать 20 персонажей. При наведении на персонажа должна выйти информация о нем. У меня выходить информация обо всех персонажей. Также не смог реализовать кнопку вперед и назад, чтобы показать следующих. Думал передать ссылку на next и previous, видимо так не работает. Как можно это исправить?

let run = async() => {
  let pokemonUrl = 'https://pokeapi.co/api/v2/pokemon/';
  let response = await fetch(pokemonUrl);
  let pokemon = await response.json();
  console.log(pokemon);
  $('.previous').attr('href', pokemon.previous)
  $('.next').attr('href', pokemon.next)
  let pokemonResults = pokemon.results;
  pokemonResults.forEach(element => {
    $('<li>').appendTo('ul').text(element.name).addClass('list');
    for (let i in element.url) {
      fetch('https://pokeapi.co/api/v2/pokemon/' + i)
        .then((res) => res.json())
        .then((res) => {
          console.log(res);
          $('<div>').appendTo('.block').html('Name: ' + res.name);
          $('<div>').appendTo('.block').html('Height: ' + res.height);
          $('<div>').appendTo('.block').html('Weight: ' + res.weight);
          $('<div>').appendTo('.block').html('Type: ' + res.types[0]['type']['name']);
          $('<img>').appendTo('.block').addClass('image').attr('src', res.sprites['other']['official-artwork']['front_default'])
        })
    }
  })
  let block = $('<div>').appendTo('li').addClass('block');
}
run()
ul {
  margin-left: 50px;
}

.list {
  cursor: pointer;
  margin-bottom: 10px;
}

.previous {
  margin-left: 20px;
}

.next {
  margin-left: 100px;
}

.block {
  width: 200px;
  padding: 10px;
  border: 1px solid #000;
  display: none;
}

li:hover div {
  display: block;
}

.image {
  width: 100px;
  height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
</ul>
<a href="" class="previous">Previous</a>
<a href="" class="next">Next</a>


Ответы (1 шт):

Автор решения: Alex Krass

Здесь сразу несколько проблем в коде.

Итерация по строке дает номера элементов, вам же нужно обращаться по самому element.url.

//Демонстрация проблемы
for (let i in "https://pokeapi.co/api/v2/pokemon/") {
    console.log(i)
}

Дальше вам нужно вставлять значения не во все элементы подряд, а в конкретный элемент, сгенерированном на данном шаге. Вместо $('<div>').appendTo('li').addClass('block') писать конкретный элемент DOM дерева $('<div>').appendTo(elementLIDom).addClass('block'), который вы создали изначально. Тоже самое с другими элементами, их надо создавать в конкретном элементе.

let elementLIDom = $('<li>').appendTo('ul');
let elementBlockDom = $('<div>').appendTo(elementLIDom)...;
$('<div>').appendTo(elementBlockDom )...;

Ну и в конце, вам нужно заново запускать фукнция получения следующих покемонов, очищая при этом текущий список и отписываясь от всех событий. Так же останавливая событие, чтобы не совершался настоящий переход по ссылке.

$('.previous').off('click').attr('href', pokemon.previous).click((event) => {
    if(pokemon.previous){
      $('li').remove()
      run(pokemon.previous)
    } 
    event.stopPropagation()
    return false;
})

Итоговый код

let run = async(url) => {
  let pokemonUrl = url ?? 'https://pokeapi.co/api/v2/pokemon/';
  let response = await fetch(pokemonUrl);
  let pokemon = await response.json();
  $('.previous').off('click').attr('href', pokemon.previous).click((event) => {
      if(pokemon.previous){
        $('li').remove()
        run(pokemon.previous)
      } 
      event.stopPropagation()
      return false;
  })
  $('.next').off('click').attr('href', pokemon.next).click((event) => {
      if(pokemon.next) {
        $('li').remove()
        run(pokemon.next)
      }
      event.stopPropagation()
      return false;
  })
  
  pokemon.results.forEach(element => {
    let li = $('<li>').appendTo('ul').text(element.name).addClass('list');
    let block = $('<div>').appendTo(li).addClass('block');
    fetch(element.url)
      .then((res) => res.json())
      .then((res) => {
        $('<div>').appendTo(block).html('Name: ' + res.name);
        $('<div>').appendTo(block).html('Height: ' + res.height);
        $('<div>').appendTo(block).html('Weight: ' + res.weight);
        $('<div>').appendTo(block).html('Type: ' + res.types[0]['type']['name']);
        $('<img>').appendTo(block).addClass('image').attr('src', res.sprites['other']['official-artwork']['front_default'])
      })
  })
}
run()
ul {
  margin-left: 50px;
}

.list {
  cursor: pointer;
  margin-bottom: 10px;
}

.previous {
  margin-left: 20px;
}

.next {
  margin-left: 100px;
}

.block {
  width: 200px;
  padding: 10px;
  border: 1px solid #000;
  display: none;
}

li:hover div {
  display: block;
}

.image {
  width: 100px;
  height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
</ul>
<a href="" class="previous">Previous</a>
<a href="" class="next">Next</a>

→ Ссылка