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

使用JavaScript筛选电影列表:解决类型筛选及data未定义问题

Fixing "TypeError: data is undefined" and Implementing Genre Filtering for Your Movie List

Let's break down the issues in your code and fix them step by step:

1. The "data is undefined" Error

First off, that error happens because of variable scope. You declared var data inside the if (this.readyState === 4 && this.status === 200) block, which means it only exists inside that block. When you try to log data.movies.categories outside of that block, data hasn't been defined yet (either the request hasn't finished, or it failed).

Also, data.movies is an array—you can't access data.movies.categories directly; you need to loop through individual movie objects instead.

2. Missing Genre Filter Functionality

Your current code doesn't listen for changes on the dropdown menu, so selecting a genre won't trigger any filtering. Plus, some movies have multiple categories (like "action,fantasy"), so a simple == check won't work—we need to check if the selected genre is present in the movie's category list.

Fixed Code Implementation

Here's the revised JavaScript code with all issues resolved:

window.addEventListener("load", setup);
// Declare data in a higher scope so it's accessible to the filter function
let data;

function setup() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'data/data.json', true);
  xhr.onreadystatechange = function() {
    if (this.readyState === 4 && this.status === 200) {
      data = JSON.parse(this.responseText);
      renderMovies(data.movies);
      populateGenres(data.categories);
      // Add event listener for genre selection
      document.getElementById('selection').addEventListener('change', filterMoviesByGenre);
    }
  }
  xhr.onerror = function() {
    console.log("Error fetching data");
  }
  xhr.send();
}

// Function to populate the genre dropdown
function populateGenres(categories) {
  let genreHtml = '<option>-- Select Genre --</option>';
  categories.forEach(category => {
    genreHtml += `<option>${category}</option>`;
  });
  document.getElementById('selection').innerHTML = genreHtml;
}

// Function to render movie list
function renderMovies(movies) {
  let output = '';
  movies.forEach(movie => {
    output += `
      <ul class="movie-item">
        <li>Title: ${movie.title}</li>
        <li>Category: ${movie.categories}</li>
      </ul>
    `;
  });
  document.getElementById('output').innerHTML = output;
}

// Function to filter movies by selected genre
function filterMoviesByGenre() {
  const selectedGenre = this.value.trim();
  const movieItems = document.querySelectorAll('.movie-item');

  movieItems.forEach((item, index) => {
    const movieCategories = data.movies[index].categories.split(',').map(cat => cat.trim());
    // Show all movies if no genre is selected, else check if genre matches
    if (selectedGenre === '-- Select Genre --') {
      item.classList.remove('hidden');
    } else if (!movieCategories.includes(selectedGenre)) {
      item.classList.add('hidden');
    } else {
      item.classList.remove('hidden');
    }
  });
}

Key Changes Made:

  • Scoped data correctly: Declared data outside the XHR callback so it's accessible to the filter function.
  • Split code into reusable functions: Separated rendering movies, populating genres, and filtering into distinct functions for better readability.
  • Handled multiple categories: Used split(',') to turn a movie's category string into an array, then trimmed whitespace to match genre values accurately.
  • Added dropdown change listener: The filterMoviesByGenre function runs every time the user selects a new genre, showing/hiding movies accordingly.
  • Fixed the loop issue: Your original loop ran for the length of both data.movies and data.categories at the same time, which would cause mismatches (since there are more movies than categories). We now use forEach to loop through each array separately.

CSS Note

Don't forget to add the hidden class in your CSS to actually hide the movie items:

.hidden {
  display: none;
}

内容的提问来源于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:17:16