JavaScript处理含重复值的对象时,元素类名切换功能失效的解决方法咨询
JavaScript处理含重复值的对象时,元素类名切换功能失效的解决方法咨询
我来帮你分析问题根源,再给出可行的解决方案~
首先看你原代码里的几个关键问题:
- 第一个循环对
Object.entries的使用完全错误:Object.entries(projectSkillsMap).map((il, value) => {})的参数顺序搞反了,Object.entries返回的是[键名, 对应值]的数组,正确参数应该是([keyEntry, skillArray]) => {};而且你后面用document.getElementById(value),这里的value其实是数组的索引,不是skill的id,根本找不到元素。 - 用
toggle处理类名是核心bug:因为你的skill id在多个project里重复,切换project时toggle会根据元素当前状态来回切换类名,比如skill_2同时在project1和project2里,从project1切到project2时,toggle可能会先删再加,导致最终状态不符合预期。 - 后续
Object.values循环逻辑也有问题:el是整个skill数组,你用document.getElementById(el)根本找不到元素,因为参数需要是字符串id,不是数组。
正确的思路应该是先统一重置所有skill按钮的状态,再给当前选中的project对应的skill添加类,完全避开toggle带来的状态混乱,具体代码如下:
const projectSkillsMap = { 'project1': ['skill_2', 'skill4', 'skill5'], 'project2': ['skill1', 'skill_2', 'skill4', 'skill5', 'skill6'], 'project3': ['skill1', 'skill_2', 'skill3', 'skill4', 'skill5', 'skill6'] } function chooseProject(key) { // 第一步:收集所有不重复的skill id,统一移除它们的button_click类 const allSkillIds = new Set(); // 遍历所有project的skill数组,用Set去重 Object.values(projectSkillsMap).forEach(skills => { skills.forEach(skillId => allSkillIds.add(skillId)); }); // 移除每个skill元素的类(加判断避免找不到元素报错) allSkillIds.forEach(skillId => { const element = document.getElementById(skillId); if (element) element.classList.remove('button_click'); }); // 第二步:给当前选中project对应的skill添加button_click类 const targetSkills = projectSkillsMap[key]; if (targetSkills) { // 确保传入的key存在于对象中 targetSkills.forEach(skillId => { const element = document.getElementById(skillId); if (element) element.classList.add('button_click'); }); } }
这个方案的优势:
- 先统一重置所有skill的状态,不管之前是什么情况,都回到初始无类的状态,彻底避免历史状态干扰。
- 用
Set收集skill id去重,避免重复操作同一个元素,提升性能。 - 只给当前选中的project对应的skill添加类,逻辑清晰,不管skill id在多少个project里重复,都能保证最终只有当前project的skill有
button_click类。
这样修改后,不管你的projectSkillsMap里有多少重复的skill id,点击project按钮后都能正确显示对应的高亮skill啦~
备注:内容来源于stack exchange,提问作者NanoMuffin
相关产品推荐
相关产品推荐

