如何用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
相关产品推荐
相关产品推荐

