改造<select multiple>菜单属性过滤JS,支持多选及多菜单适配
多下拉菜单多选过滤解决方案
问题背景
现有基于<select>的内容过滤功能,已给菜单添加multiple属性,但当前JS仅能识别最后一个选中项,无法实现多选过滤;同时需要扩展支持另外两个同样基于data-mc-conditions属性的过滤菜单,要求继续使用hidden1类控制元素显示/隐藏。
修改后的完整代码
HTML 代码
<!-- 三个过滤下拉菜单,统一添加filter-select类便于批量处理 --> <select multiple="multiple" class="filter-select" id="version-select"> <option value="Default.Version 1">Version 1</option> <option value="Default.Version 2">Version 2</option> <option value="Default.Version 3">Version 3</option> <option value="allprod">All</option> </select> <select multiple="multiple" class="filter-select" id="category-select"> <!-- 示例分类选项,可根据实际需求自定义 --> <option value="Default.Category A">Category A</option> <option value="Default.Category B">Category B</option> <option value="allcat">All Categories</option> </select> <select multiple="multiple" class="filter-select" id="type-select"> <!-- 示例类型选项,可根据实际需求自定义 --> <option value="Default.Type X">Type X</option> <option value="Default.Type Y">Type Y</option> <option value="alltype">All Types</option> </select> <!-- 内容段落:将原MadCap:conditions改为标准data-mc-conditions属性,确保JS可正确读取 --> <p class="filter" data-mc-conditions="Default.Version 1,Default.allprod">This is content for Version 1</p> <p class="filter" data-mc-conditions="Default.Version 2,Default.allprod">This is content for Version 2</p> <p class="filter" data-mc-conditions="Default.Version 3,Default.allprod">This is content for Version 3</p> <p class="filter" data-mc-conditions="Default.Version 1,Default.Version 2,Default.allprod">This is content for V1 and V2</p> <p class="filter" data-mc-conditions="Default.Version 1,Default.Version 3,Default.allprod">This is content for V1 and V3</p> <p class="filter" data-mc-conditions="Default.Version 2,Default.Version 3,Default.allprod">This is content for V2 and V3</p> <p class="filter" data-mc-conditions="Default.allprod,Default.Version 1,Default.Version 2,Default.Version 3">This is content for V1, V2, and V3</p>
JavaScript 代码
// 页面加载完成后执行初始化:恢复保存的选中状态+执行一次过滤 document.addEventListener('DOMContentLoaded', () => { restoreFilterState(); filterContent(); }); // 给所有过滤菜单绑定change事件 document.querySelectorAll('.filter-select').forEach(select => { select.addEventListener('change', filterContent); }); function filterContent() { // 获取所有需要过滤的元素 const targetElements = document.querySelectorAll('[data-mc-conditions]'); // 收集每个过滤菜单的选中值,按菜单分组 const filterGroups = Array.from(document.querySelectorAll('.filter-select')).map(select => { return Array.from(select.selectedOptions).map(opt => opt.value.trim()); }); // 遍历每个元素判断是否显示 targetElements.forEach(element => { // 解析元素的条件列表 const elementConditions = element.getAttribute('data-mc-conditions') .split(',') .map(cond => cond.trim()); // 过滤逻辑:所有菜单组的条件都需满足(组内多选为OR,组间为AND) const shouldDisplay = filterGroups.every(group => { // 菜单无选中值时默认通过 if (group.length === 0) return true; // 检查元素是否匹配组内任意选中值,或匹配全量选项(如allprod) return group.some(filterVal => { return elementConditions.includes(filterVal) || filterVal.startsWith('all'); }); }); // 控制元素显示/隐藏 shouldDisplay ? element.classList.remove('hidden1') : element.classList.add('hidden1'); }); // 保存当前选中状态到localStorage saveFilterState(); } // 保存过滤菜单的选中状态 function saveFilterState() { document.querySelectorAll('.filter-select').forEach(select => { const selectedVals = Array.from(select.selectedOptions).map(opt => opt.value); localStorage.setItem(`filter_${select.id}`, JSON.stringify(selectedVals)); }); } // 恢复之前保存的过滤状态 function restoreFilterState() { document.querySelectorAll('.filter-select').forEach(select => { const savedVals = localStorage.getItem(`filter_${select.id}`); if (savedVals) { const vals = JSON.parse(savedVals); Array.from(select.options).forEach(opt => { opt.selected = vals.includes(opt.value); }); } }); }
核心修改说明
- 多选支持:不再仅获取单个选中项,而是收集每个菜单的所有选中值,实现组内多选OR逻辑。
- 多菜单兼容:通过
filter-select类批量处理所有过滤菜单,无需为每个菜单单独编写事件绑定逻辑。 - 逻辑优化:采用组间AND、组内OR的过滤规则(元素需满足每个菜单组的至少一个选中条件),同时保留了
allprod这类全量选项的匹配逻辑。 - 性能提升:用
document.querySelectorAll替代原有的全DOM遍历,元素选择更高效。 - 状态持久化:将每个菜单的选中状态单独保存到localStorage,页面刷新后可自动恢复之前的过滤状态。
- 属性标准化:将原非标准的
MadCap:conditions改为标准data-mc-conditions属性,确保跨浏览器兼容性(若需保留MadCap属性,可将JS中data-mc-conditions改为MadCap:conditions)。
内容的提问来源于stack exchange,提问作者Whittark11
相关产品推荐
相关产品推荐

