JS多条件动态筛选餐厅对象 5星筛选失效与过滤逻辑修复
问题原因
现有代码存在3个核心问题导致筛选失效:
- 过滤逻辑完全是反向排除设计:
ruleOut函数的规则是「匹配到过滤字段值就排除该餐厅」,但5星筛选是正向匹配需求(勾选后需要保留5星餐厅、排除非5星),逻辑完全冲突,所以勾选5星反而会把所有5星餐厅排除掉 - 复选框取值逻辑存在漏洞:未勾选选项时会向值数组插入空字符串,后续判断时空字符串会参与匹配,导致无勾选时过滤结果异常
- 前三个复选框的value和label语义完全相反:比如标注「FastFood」的复选框value写的是
dinner、标注「Open24」的复选框value写的是no、标注「Price $$」的复选框value写的是$,完全靠反向排除逻辑勉强凑出效果,和5星的正向筛选需求无法兼容
修复实现
直接把反向排除逻辑改成和用户操作直觉一致的正向多条件匹配:勾选某条件就保留符合该条件的餐厅,多勾选时取结果交集,未勾选的条件不做限制,同时修正复选框value对应关系。
修正后HTML部分(复选框value对齐语义)
<div class="container"> <div id="buttons"> <form action="" id="form"> <input type="checkbox" id="fastfood" name="check" value="fastfood"> <label for="fastfood"> FastFood</label> <input type="checkbox" id="open24" name="check" value="yes"> <label for="open24"> Open24</label> <input type="checkbox" id="priceFilter" name="check" value="$$"> <label for="priceFilter"> Price $$</label> <input type="checkbox" id="fiveStar" name="check" value="5"> <label for="fiveStar"> 5 Stars</label> <input type="submit" value="Filter"> </form> </div> <div id="target"> <table> <tr> <th>Restaurant</th> <th>Type</th> <th>Open 24</th> <th>Price</th> <th>5 Stars</th> </tr> <tbody id="table"></tbody> </table> </div> </div>
修正后JS部分(正向筛选逻辑)
let table = document.getElementById('table'); let form = document.getElementById('form'); const restaurants = [ {name: "dennys", type: "dinner", open: "yes", price: "$$", stars: "5"}, {name: "mcdonalds", type: "fastfood", open: "no", price: "$", stars: "3"}, {name: "rubios", type: "fastfood", open: "yes", price: "$$", stars: "4"}, {name: "polloloco", type: "fastfood", open: "no", price: "$", stars: "5"}, {name: "kfc", type: "fastfood", open: "no", price: "$", stars: "3"}, {name: "deltaco", type: "fastfood", open: "no", price: "$", stars: "1"}, {name: "olivegarden", type: "dinner", open: "no", price: "$$", stars: "4"}, {name: "fiveguys", type: "fastfood", open: "no", price: "$$", stars: "5"} ] displayer(restaurants) // 正向多条件筛选:返回满足所有选中条件的餐厅 function filterRestaurants(arr, selectedFilters) { return arr.filter(restaurant => { // 遍历所有选中的筛选条件,全部匹配才保留 for (const [field, value] of Object.entries(selectedFilters)) { if (restaurant[field] !== value) return false } return true }) } form.addEventListener('submit', (evt) => { evt.preventDefault() const checkboxes = document.getElementsByName('check'); // 字段和复选框顺序对应:type、open、price、stars const fieldMap = ['type', 'open', 'price', 'stars'] const selectedFilters = {} for (let i = 0; i < checkboxes.length; i++) { // 只收集勾选的条件,未勾选的不加入筛选规则 if (checkboxes[i].checked) { selectedFilters[fieldMap[i]] = checkboxes[i].value } } const filtered = filterRestaurants(restaurants, selectedFilters); displayer(filtered) }) function displayer(filtered) { table.innerHTML = ""; filtered.forEach(rest => { table.innerHTML += ` <tr> <td>${rest.name}</td> <td>${rest.type}</td> <td>${rest.open}</td> <td>${rest.price}</td> <td>${rest.stars}</td> </tr> ` }) }
原有CSS代码不需要修改,保持样式即可。
修复后效果
- 单独勾选「5 Stars」:返回所有星级为5的餐厅(dennys、polloloco、fiveguys)
- 组合勾选「FastFood」+「5 Stars」:返回快餐类5星餐厅(polloloco、fiveguys)
- 任意多条件组合都可以正常取交集筛选,无勾选时返回全部餐厅,完全符合操作预期。
内容的提问来源于stack exchange,提问作者Good4you
相关产品推荐
相关产品推荐

