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

API调用求助:页面加载正常但搜索结果无法正确展示

问题分析与解决方案

我帮你排查了一下,搜索功能失效主要有两个核心问题,咱们一步步解决:

1. API返回数据结构不匹配

TVMaze的搜索接口(/search/shows)返回的数组结构和剧集列表接口(/shows)不一样!搜索接口返回的是包含show属性的对象数组,每个元素是{ show: 剧集信息对象, score: 匹配分数 },而你在渲染时直接用show.image、show.name,这会导致无法读取到正确的属性,自然渲染不出内容。

2. 事件触发时机不合理

你用了keydown事件,这会在用户每按下一个按键时就发起请求(比如输入"abc"会发3次请求),不仅浪费资源,还可能导致页面频繁刷新。更合理的做法是监听keyup事件,并且只在用户按下回车键时发起搜索,或者做防抖处理(避免频繁请求)。


修正后的完整代码

JavaScript部分

// 展示评分最高的10部剧集
fetch('https://api.tvmaze.com/shows')
  .then(blob => blob.json())
  .then(json => {
    // 修正slice:slice(0,10)才是取前10个,之前的slice(0,9)只有9个
    const topTenShows = json
      .filter(show => show.rating.average)
      .sort((a, b) => b.rating.average - a.rating.average) // 简化排序逻辑
      .slice(0, 10)
    return topTenShows
  })
  .then(shows => renderShows(shows)) // 抽离渲染逻辑,复用代码

// 抽离渲染函数,避免重复代码
function renderShows(shows) {
  const app = document.getElementById('app')
  app.innerHTML = shows.map(show => `
    <div class="col-sm movie-content">
      <!-- 用可选链处理图片不存在的情况,避免报错 -->
      <img src="${show.image?.medium || ''}">
      <div class="movie-info">
        <h5>${show.name}</h5>
        <span>Rating: ${show.rating.average}</span>
        <br />
        <span>Genres: ${show.genres.join(', ')}</span> <!-- 修正文字:把Rating改成Genres,更准确 -->
      </div>
    </div>
  `).join('') // join()不传参数会默认加逗号,传空字符串避免多余分隔符
}

// 搜索功能
function searchTvAmaze (event) {
  // 只在按下回车键时发起搜索
  if (event.key !== 'Enter') return
  
  const searchQuery = event.target.value.trim()
  // 如果搜索框为空,返回展示top10
  if (!searchQuery) {
    fetch('https://api.tvmaze.com/shows')
      .then(blob => blob.json())
      .then(json => {
        const topTenShows = json
          .filter(show => show.rating.average)
          .sort((a, b) => b.rating.average - a.rating.average)
          .slice(0, 10)
        renderShows(topTenShows)
      })
    return
  }

  fetch(`https://api.tvmaze.com/search/shows?q=${encodeURIComponent(searchQuery)}`) // 用encodeURIComponent处理特殊字符
    .then(blob => blob.json())
    .then(searchResults => {
      // 提取出每个结果里的show对象
      const shows = searchResults.map(item => item.show)
      renderShows(shows)
    })
    .catch(err => console.error('搜索出错:', err)) // 添加错误捕获,方便调试
}

const inputSearchField = document.querySelector('.inputSearchField')
inputSearchField.addEventListener('keyup', searchTvAmaze) // 改成keyup事件

HTML部分(无需修改,保持原样)

<div class="col-sm-10 main-content">
  <div class="search">
    <input class="inputField inputSearchField" type="text" placeholder="Search...">
  </div>
  <div class="container">
    <div id="app" class="row">
    </div>
  </div>
</div>

关键修改点说明

  • 统一渲染逻辑:抽离renderShows函数,避免重复编写DOM渲染代码,后续维护更方便。
  • 适配搜索API结构:搜索结果通过searchResults.map(item => item.show)提取出真正的剧集对象,再传给渲染函数。
  • 优化事件触发:改成keyup事件并判断回车键,避免不必要的请求;同时处理搜索框为空的情况,返回展示top10剧集。
  • 容错处理:用可选链show.image?.medium处理图片不存在的情况,避免控制台报错;添加catch捕获请求错误。
  • 细节优化:排序逻辑简化为b.rating.average - a.rating.average;join('')避免渲染时出现多余逗号;用encodeURIComponent处理搜索关键词里的特殊字符(比如空格、中文等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:53:35