动态展示嵌套对象问题:下拉选电影始终显示最后一部演员列表
问题分析与修复方案
你的代码出现无论选择哪部电影,始终显示《Fantastic Mr. Fox》演员列表的问题,核心是两个关键错误导致的:
错误1:Option的value属性设置无效
HTML的<option>标签value属性仅支持字符串类型,但你直接将电影对象赋值给它:
movieOptionElement.setAttribute('value', movieData[movieName]);
对象会被强制转换为字符串[object Object],导致所有选项的value完全相同,无法区分选中的电影。
错误2:重复绑定change事件引发闭包问题
你在遍历电影列表的循环中,每次调用dropDown()给下拉框新增一个change事件监听:
for (let movieName in movieData) { // ... 创建option的代码 dropDown(movieData[movieName]["cast"]) };
循环执行4次后,下拉框会绑定4个事件监听。由于闭包特性,最后一次绑定的监听会保留最后一部电影的演员列表,无论选择哪个选项,最终都会触发这个最后绑定的监听,显示最后一部的演员。
修复后的完整代码
HTML部分
Movie list: <span id="movie-list"></span> Select a movie: <select id="movies-drop-down"></select><br> movie-details: <span id="movie-details"></span>
JavaScript部分
let movieData = { "The Darjeeling Limited": { plot: "A year after their father's funeral, three brothers travel across India by train in an attempt to bond with each other.", cast: ["Jason Schwartzman", "Owen Wilson", "Adrien Brody"], runtime: 151, rating: 7.2, year: 2007, }, "The Royal Tenenbaums": { plot: "The eccentric members of a dysfunctional family reluctantly gather under the same roof for various reasons", rating: 7.6, year: 2001, cast: ["Gene Hackman", "Gwnyeth Paltrow", "Anjelica Huston"], runtime: 170, }, "Fantastic Mr. Fox": { year: 2009, plot: "An urbane fox cannot resist returning to his farm raiding ways and then must help his community survive the farmers' retaliation.", cast: [ "George Clooney", "Meryl Streep", "Bill Murray", "Jason Schwartzman", ], runtime: 147, rating: 7.9, }, "The Grand Budapest Hotel": { rating: 8.1, runtime: 159, year: 2014, plot: "A writer encounters the owner of an aging high-class hotel, who tells him of his early years serving as a lobby boy in the hotel's glorious years under an exceptional concierge.", cast: ["Ralph Fiennes", "F. Murray Abraham", "Mathieu Amalric"], }, }; // 渲染电影名称到页面 const movieListNames = Object.keys(movieData); function addSpaceToName(array) { for (let movie = 1; movie < array.length; movie++) { array[movie] = " " + array[movie]; } return array; } addSpaceToName(movieListNames); document.getElementById("movie-list").innerHTML = movieListNames; const movieDetails = document.getElementById('movie-details'); const moviesDropDown = document.getElementById('movies-drop-down'); // 生成下拉选项 for (let movieName in movieData) { let movieOptionElement = document.createElement("option"); // 将电影名称作为option的value,确保能准确识别选中项 movieOptionElement.setAttribute('value', movieName); let movieOptionText = document.createTextNode(movieName); movieOptionElement.appendChild(movieOptionText); moviesDropDown.appendChild(movieOptionElement); }; // 仅绑定一次change事件,根据选中的电影名称获取对应演员 moviesDropDown.addEventListener('change', (event) => { const selectedMovie = event.target.value; if (selectedMovie) { // 将演员数组转为逗号分隔的字符串展示 movieDetails.innerHTML = movieData[selectedMovie].cast.join(', '); } });
关键修复点说明
- 修正Option的value:将
value设置为电影名称字符串,选中时可直接通过该值从movieData中匹配对应的电影数据。 - 单次事件绑定:将change事件监听移到循环外部,仅绑定一次,每次触发时根据当前选中的
value动态获取对应演员列表,彻底避免重复绑定和闭包问题。
内容的提问来源于stack exchange,提问作者generateGeorgina
相关产品推荐
相关产品推荐

