如何使用两个自定义下拉菜单按两个不同data属性筛选内容?
自定义下拉多条件筛选修复方案
现有问题梳理
- 双事件绑定冲突:所有
.custom__option元素同时绑定了两个点击事件,点击任意选项会同时执行故事类型筛选和年份筛选,非对应类型的选项缺少对应dataset属性,传入值为undefined导致筛选结果异常 - 筛选逻辑互斥:两个筛选函数独立控制元素显隐,无法支持两个筛选条件同时生效
- 年份选项属性错误:HTML中年份下拉的2018、2017、2016选项的
data-year属性值全部写错,和实际年份不匹配 - 重置按钮逻辑错误:自定义下拉不会触发原生
change事件,导致重置按钮无法正常显示;重置函数中将筛选函数误当做DOM元素调用,无法重置下拉选中状态
修复后的完整代码
JS代码
// 存储当前选中的筛选条件 let currentFilter = { story: 'All', year: 'All' } // 下拉展开收起逻辑 for (const dropdown of document.querySelectorAll(".custom__select-wrapper")) { dropdown.addEventListener("click", function () { this.querySelector(".custom__select").classList.toggle("open"); }); } // 故事类型下拉选项点击 for (const option of document.querySelectorAll("#storyFilter .custom__option")) { option.addEventListener("click", function () { if (!this.classList.contains("selected")) { this.parentNode.querySelector(".custom__option.selected").classList.remove("selected"); this.classList.add("selected"); this.closest(".custom__select").querySelector(".custom__select-trigger span").textContent = this.textContent; currentFilter.story = this.dataset.value || 'All'; updateFilter(); // 显示重置按钮 document.querySelector("#selectedFilter").classList.remove("hidden"); } }); } // 年份下拉选项点击 for (const option of document.querySelectorAll("#yearFilter .custom__option")) { option.addEventListener("click", function () { if (!this.classList.contains("selected")) { this.parentNode.querySelector(".custom__option.selected").classList.remove("selected"); this.classList.add("selected"); this.closest(".custom__select").querySelector(".custom__select-trigger span").textContent = this.textContent; currentFilter.year = this.dataset.year || 'All'; updateFilter(); // 显示重置按钮 document.querySelector("#selectedFilter").classList.remove("hidden"); } }); } // 点击外部关闭下拉 window.addEventListener("click", function (e) { for (const select of document.querySelectorAll(".custom__select")) { if (!select.contains(e.target)) { select.classList.remove("open"); } } }); // 统一筛选逻辑,支持双条件同时生效 function updateFilter() { const list = document.querySelectorAll(".list.article"); for (const article of list) { const matchStory = currentFilter.story === 'All' || article.dataset.story === currentFilter.story; const matchYear = currentFilter.year === 'All' || article.dataset.year === currentFilter.year; article.classList.toggle('hidden', !(matchStory && matchYear)); } } // 重置逻辑 function clearSelection() { // 重置故事类型下拉 const storyDefault = document.querySelector("#storyFilter .custom__option:first-child"); storyDefault.click(); document.querySelector("#storyFilter").closest(".custom__select").querySelector(".custom__select-trigger span").textContent = "Story Type"; // 重置年份下拉 const yearDefault = document.querySelector("#yearFilter .custom__option:first-child"); yearDefault.click(); document.querySelector("#yearFilter").closest(".custom__select").querySelector(".custom__select-trigger span").textContent = "Year"; // 隐藏重置按钮 document.querySelector("#selectedFilter").classList.add("hidden"); // 重置所有文章显示 [...document.querySelectorAll(".article")].forEach(article => article.classList.remove("hidden")); // 重置筛选条件存储 currentFilter = {story: 'All', year: 'All'}; }
需修改的HTML年份选项部分
<div class="custom__options" id="yearFilter"> <span class="custom__option selected">All</span> <span class="custom__option" data-year="2020">2020</span> <span class="custom__option" data-year="2019">2019</span> <span class="custom__option" data-year="2018">2018</span> <span class="custom__option" data-year="2017">2017</span> <span class="custom__option" data-year="2016">2016</span> </div>
修复效果说明
- 两个筛选条件可同时生效,支持交叉筛选
- 年份筛选功能正常
- 重置按钮可正常显示、点击后可重置所有筛选状态和内容显示
- 下拉交互逻辑保持不变
内容的提问来源于stack exchange,提问作者Millhorn
相关产品推荐
相关产品推荐

