You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript宝可梦图鉴排序问题排查及其他排序方式咨询

修复宝可梦图鉴排序问题 + 额外排序思路

现有代码的核心问题

  • 未保留宝可梦原始数据集合:当前代码直接将数据渲染为DOM元素,没有存储原始数据数组,导致排序时pokemon.sort完全无效(pokemon是单个DOM元素,不是数据集合)
  • 排序后未正确重新渲染:事件监听里的createPokemonCard(data)无意义,data未定义,也未清空原有卡片再重新生成
  • 冗余变量定义:sortInput被重复声明,属于无效代码

修复后的完整代码

修复后的JavaScript代码

const pokeContainer = document.getElementById('poke_Container')
const poke_Num = 150
const sortInput = document.getElementById("filter-Buttons")
// 新增:存储所有宝可梦原始数据的数组,作为排序操作的基础
const allPokemon = []

const cardDetails = async () => {
    for (let i = 1; i <= poke_Num; i++) {
        await getPokemon(i)
    }
    // 初始渲染所有卡片
    renderPokemonCards(allPokemon)
}

const getPokemon = async (id) => {
    const url = `https://pokeapi.co/api/v2/pokemon/${id}`;
    const response = await fetch(url);
    const data = await response.json();
    // 将数据存入数组,而非直接渲染
    allPokemon.push(data)
}

cardDetails();

// 拆分渲染函数:负责清空容器 + 根据传入的数组批量生成卡片
function renderPokemonCards(pokemonList) {
    pokeContainer.innerHTML = ''
    pokemonList.forEach(data => createPokemonCard(data))
}

function createPokemonCard(data) {
    const pokemon = document.createElement('div')
    pokemon.classList.add('pokemon')

    const name = data.name[0].toUpperCase() + data.name.slice(1);
    const poketure = data.sprites["front_default"];
    const poketype = data.types.map((type) => type.type.name).join(" ")

    const pokemonInnerHTML = `
        <div class='image-Container'>
            <img src="${poketure}" alt="${name}">
        </div>
        <div class='info'>
            <h3 class='poke-Name'>${name}</h3>         
            <span class="poke-id">#${data.id.toString().padStart(3, "0")}</span>
            <br>
            <div class="poke-type">Type: ${poketype}</div>
        </div>
    `
    pokemon.innerHTML = pokemonInnerHTML;
    pokeContainer.appendChild(pokemon);
}

sortInput.addEventListener('change', (event) =>{
    const sortBy = event.target.value
    // 复制原始数组,避免修改原始数据集合(可选,保留初始顺序备份)
    let sortedPokemon = [...allPokemon]

    switch (sortBy) {
        case 'id-asc':
            sortedPokemon.sort((a, b) => a.id - b.id)
            break
        case 'id-desc':
            sortedPokemon.sort((a, b) => b.id - a.id)
            break
        case 'name-asc':
            // 用localeCompare替代手动字符串比较,代码更简洁且支持多语言排序
            sortedPokemon.sort((a, b) => a.name.localeCompare(b.name))
            break
        case 'name-desc':
            sortedPokemon.sort((a, b) => b.name.localeCompare(a.name))
            break        
    }

    // 调用渲染函数展示排序结果
    renderPokemonCards(sortedPokemon)
})

关键改动说明

  • 新增allPokemon数组存储原始数据,这是排序功能的核心基础
  • 拆分renderPokemonCards函数,统一处理容器清空和卡片批量生成,避免重复代码
  • 排序时复制原始数组,防止修改初始数据集合
  • 用localeCompare简化字符串排序逻辑,兼容性更好
  • 移除冗余的sortInput声明

额外排序方式建议

除了ID和名称排序,还可以实现这些实用的排序逻辑:

  • 按主类型排序:先按宝可梦的第一个类型分组,同类型内再按ID/名称排序
    // 示例:主类型升序,同类型按ID升序
    sortedPokemon.sort((a, b) => {
        const typeA = a.types[0].type.name
        const typeB = b.types[0].type.name
        if (typeA !== typeB) {
            return typeA.localeCompare(typeB)
        }
        return a.id - b.id
    })
    
  • 按身高/体重排序:利用API返回的height和weight字段排序
    // 身高升序
    sortedPokemon.sort((a, b) => a.height - b.height)
    // 体重降序
    sortedPokemon.sort((a, b) => b.weight - a.weight)
    
  • 按名称长度排序:比较名称的字符长度
    sortedPokemon.sort((a, b) => a.name.length - b.name.length)
    

内容的提问来源于stack exchange,提问作者Mekayla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 18:51:33