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

如何用JavaScript实现电影列表分类筛选?解决data未定义报错

解决分类筛选电影的问题并修复data is undefined报错

先来说你碰到的TypeError: data is undefined问题——你把console.log(data.movies.categories)写在了XHR请求成功的判断块外面了!那个data变量是在if (this.readyState === 4 && this.status === 200)这个代码块里定义的,出了这个块就不属于当前作用域了,自然访问不到。把这行console移到if块内部,或者直接删掉就能解决这个报错。

接下来咱们搞定分类筛选的功能,我帮你重构了代码,让逻辑更清晰、复用性更强:

第一步:抽离渲染电影的独立函数

把渲染电影列表的逻辑单独写成一个函数,这样初始化和筛选的时候都能直接调用,不用重复写冗余代码:

function renderMovies(movies) {
  let output = '';
  movies.forEach(movie => {
    output += `
      <ul>
        <li> Title: ${movie.title} </li>
        <li> Category: ${movie.categories} </li>
      </ul>
    `;
  });
  document.getElementById('output').innerHTML = output;
}

第二步:修复作用域+实现筛选逻辑

把请求到的数据存在setup函数的闭包里,方便后续筛选时访问;同时给下拉框添加change事件监听,每次选择分类时自动过滤并渲染对应电影:

window.addEventListener("load", setup);

function setup() {
  let movieData; // 存储请求到的完整数据,供筛选时使用
  
  // 渲染电影列表的复用函数
  function renderMovies(movies) {
    let output = '';
    movies.forEach(movie => {
      output += `
        <ul>
          <li> Title: ${movie.title} </li>
          <li> Category: ${movie.categories} </li>
        </ul>
      `;
    });
    document.getElementById('output').innerHTML = output;
  }

  // 处理分类筛选的函数
  function handleFilter() {
    const selectedGenre = this.value.trim();
    if (selectedGenre === "-- Select Genre --") {
      // 选择默认选项时,显示所有电影
      renderMovies(movieData.movies);
      return;
    }
    // 过滤出包含选中分类的电影(兼容多分类电影)
    const filteredMovies = movieData.movies.filter(movie => {
      return movie.categories.split(',').some(category => category.trim() === selectedGenre);
    });
    renderMovies(filteredMovies);
  }

  // 发起XHR请求获取数据
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'data/data.json', true);
  xhr.onreadystatechange = function() {
    if (this.readyState === 4 && this.status === 200) {
      movieData = JSON.parse(this.responseText);
      
      // 渲染分类下拉框
      let genre = '<option> -- Select Genre -- </option>';
      movieData.categories.forEach(category => {
        genre += `<option> ${category} </option>`;
      });
      document.getElementById('selection').innerHTML = genre;
      
      // 初始化渲染所有电影
      renderMovies(movieData.movies);
      
      // 给下拉框绑定筛选事件
      document.getElementById('selection').addEventListener('change', handleFilter);
      
      // 调试用的console要放在这里,才能访问到movieData
      // console.log(movieData);
    }
  };
  xhr.onerror = function() { console.log("请求出错啦") };
  xhr.send();
}

关键细节说明

  • 多分类兼容:有些电影的分类是用逗号分隔的多个值(比如action,fantasy),所以用split(',')把字符串转成数组,再用some()方法检查是否包含选中的分类,确保所有相关电影都能被筛选出来。
  • 作用域修复:把movieData定义在setup函数内部,作为闭包变量,这样筛选函数就能直接访问到数据,不会出现未定义的问题。
  • 默认选项处理:当选择-- Select Genre --时,自动恢复显示所有电影,提升用户体验。

这样修改后,不仅解决了data is undefined的报错,还完美实现了分类筛选功能——选择不同分类,页面就会只显示对应类别的电影啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:14:24