基于多份JSON文件创建动态筛选菜单的技术实现请求
基于多份JSON生成动态筛选菜单
实现思路
- 整合JSON数据:加载所有目标JSON文件,提取出筛选分类(如Type、Special、Clothing)及对应选项的唯一值,整理成分类与选项的映射关系。
- 动态构建DOM结构:按照目标HTML结构,生成筛选菜单容器、分类标题、选项列表,同时设置好对应的类名、ID和
data-filter属性。 - 添加基础交互:按需实现分类标题的展开/收起逻辑,对应示例中的加号图标交互。
代码实现示例
1. 数据处理与DOM生成
// 假设多份JSON已加载并合并为mergedData数组 // 示例JSON结构:[{Type: "Human", Special: "Fireflies", Clothing: "Light Kimono"}, ...] // 定义筛选分类配置 const filterConfig = [ { category: "Type", menuId: "filter-menu_01", isActive: true }, { category: "Special", menuId: "filter-menu_02", isActive: false }, { category: "Clothing", menuId: "filter-menu_03", isActive: false } ]; // 提取分类下的唯一选项 const getUniqueOptions = (categoryKey) => { const optionSet = new Set(mergedData.map(item => item[categoryKey])); return Array.from(optionSet).sort(); }; // 创建菜单容器 const menuWrapper = document.createElement('ul'); menuWrapper.className = 'filter-menu-wrapper'; // 遍历生成每个分类菜单 filterConfig.forEach((config, idx) => { const menuItem = document.createElement('li'); menuItem.className = `filter-menu ${config.isActive ? 'is-active' : ''}`; menuItem.id = config.menuId; // 生成分类标题 const categoryTitle = document.createElement('span'); categoryTitle.className = 'filter-category'; categoryTitle.innerHTML = `${config.category}<i class='cstm-icon-glyph cstm-icon-glyph-plus'></i>`; menuItem.appendChild(categoryTitle); // 生成选项容器 const optionsContainer = document.createElement('div'); optionsContainer.className = 'filter-options'; // 添加"any"选项 const anyOption = document.createElement('span'); anyOption.className = 'filter-option'; anyOption.dataset.filter = ''; anyOption.textContent = 'any'; optionsContainer.appendChild(anyOption); // 添加分类对应选项 const options = getUniqueOptions(config.category); options.forEach(option => { const optionEl = document.createElement('span'); // 示例中Type分类的Red选项带thefirst类,可按需调整规则 const optionClass = config.category === 'Type' && option === 'Red' ? 'filter-option thefirst' : 'filter-option'; optionEl.className = optionClass; optionEl.dataset.filter = `.${config.category}${option.replace(/\s/g, '')}`; optionEl.textContent = option; optionsContainer.appendChild(optionEl); }); menuItem.appendChild(optionsContainer); menuWrapper.appendChild(menuItem); }); // 将菜单插入页面目标位置 document.body.appendChild(menuWrapper);
2. 展开/收起交互逻辑(可选)
document.querySelectorAll('.filter-category').forEach(title => { title.addEventListener('click', () => { const parentMenu = title.closest('.filter-menu'); parentMenu.classList.toggle('is-active'); // 切换图标(需提前定义减号图标类) const icon = title.querySelector('.cstm-icon-glyph'); icon.classList.toggle('cstm-icon-glyph-plus'); icon.classList.toggle('cstm-icon-glyph-minus'); }); });
注意事项
- 多份JSON加载可通过
Promise.all实现,确保数据全部加载后再生成菜单:
const jsonPaths = ['data1.json', 'data2.json', 'data3.json']; Promise.all(jsonPaths.map(path => fetch(path).then(res => res.json()))) .then(allData => { mergedData = allData.flat(); // 执行DOM生成逻辑 }) .catch(err => console.error('JSON加载失败:', err));
thefirst类的添加规则可根据实际需求修改,比如指定索引或从JSON数据中读取标记字段。
内容的提问来源于stack exchange,提问作者JavaScriptLearner
相关产品推荐
相关产品推荐

