如何在HTML页面展示动态宝可梦数据?渲染代码无输出
问题排查与解决方案
核心问题原因
forEach异步回调导致内容覆盖
forEach无法正确处理async回调,循环内的异步请求会并行执行。就算找到匹配的Pokemon并调用displayPokemon设置了内容,后续未匹配的迭代仍会进入else分支,把.pokemonBox的内容覆盖为“Pokemon not found”,最终页面显示最后一次迭代的结果。多余的await滥用
对普通数组、对象字面量用await完全无效(比如const pokemons = await data.results、const pokemonDataToShow = await {...}),虽不会直接报错,但会造成逻辑混乱。无效HTML标签
else分支里的<h>是非法标签,浏览器无法正常渲染,可能引发显示异常。请求逻辑低效
每次搜索先请求100个Pokemon列表再逐个查详情,既浪费资源又容易出问题,完全可以直接根据输入的名字请求对应详情。
修复后的代码示例
1. 优化getPokemon函数(核心修复)
async function getPokemon(e) { try { const name = document.querySelector('#pokemonName').value.trim(); if (!name) return; // 空输入直接终止 const nameLowerCase = name.toLowerCase(); // 替代自定义lowerCaseName,更稳妥 // 直接根据名字请求目标Pokemon,无需遍历列表 const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${nameLowerCase}`); if (!response.ok) throw new Error('Pokemon not found'); const pokemonDetails = await response.json(); const abilityList = pokemonDetails.abilities; const typeList = pokemonDetails.types; const pokemonDataToShow = { name: pokemonDetails.name, image: pokemonDetails.sprites.other["official-artwork"].front_default, height: pokemonDetails.height, weight: pokemonDetails.weight, abilities: abilityList.map(el => el.ability.name).join(', '), types: typeList.map(el => el.type.name).join(', ') }; displayPokemon(pokemonDataToShow); } catch (error) { document.querySelector(".pokemonBox").innerHTML = ` <h2> Pokemon not found 😞</h2> `; console.log(error); } e.preventDefault(); }
2. 修正displayPokemon及辅助函数
function displayPokemon(pokemon) { console.log(pokemon); document.querySelector(".pokemonBox").innerHTML = ` <div> <img src="${pokemon.image}" alt="${pokemon.name}" /> </div> <div class="pokemonInfo"> <h2>${capitalizeFirstLetter(pokemon.name)}</h2> <p>Height: ${pokemon.height}</p> <p>Weight: ${pokemon.weight}</p> <ul> <li>${pokemon.abilities}</li> </ul> <ul> <li>${pokemon.types}</li> </ul> </div> `; } // 确保首字母大写函数存在 function capitalizeFirstLetter(str) { return str.charAt(0).toUpperCase() + str.slice(1); }
3. 修正HTML细节并绑定事件
<body> <main> <div class="searchBox"> <input id="pokemonName" type="text" <!-- 原type值非法,改为标准text类型 --> placeholder="Pokemon name" /> <button id="search">🔎</button> </div> <div class="pokemonBox"></div> </main> <script> // 绑定搜索按钮点击事件 document.querySelector('#search').addEventListener('click', getPokemon); // 支持回车触发搜索 document.querySelector('#pokemonName').addEventListener('keypress', e => { if (e.key === 'Enter') getPokemon(e); }); </script> </body>
内容的提问来源于stack exchange,提问作者Flo
相关产品推荐
相关产品推荐

