本文介绍一种基于 css 选择器与 dom 查询的健壮方案,解决食品外卖网站中「分类筛选后仍保持每页 15 条、自动重排分页」的核心需求,避免原逻辑中仅对当前页数据过滤导致的显示断层问题。
本文介绍一种基于 css 选择器与 dom 查询的健壮方案,解决食品外卖网站中「分类筛选后仍保持每页 15 条、自动重排分页」的核心需求,避免原逻辑中仅对当前页数据过滤导致的显示断层问题。
在构建食品配送类网站的菜单系统时,一个常见但关键的交互需求是:用户勾选分类(如“Salty”“Sweet”)后,不仅应实时筛选出匹配商品,还必须重新组织分页——即确保第一页始终展示前 15 条符合条件的商品,而非仅从原始第一页中筛选剩余项。原始代码的问题在于:它始终基于 products 全量 NodeList 的原始索引(index)进行显示控制,而未考虑筛选后数据集已发生结构性变化。
要真正实现「过滤即重分页」,核心思路是:先通过 CSS 选择器精准获取当前筛选结果集,再基于该动态集合重新计算分页逻辑与可见范围。以下是优化后的完整实现方案:
✅ 关键改进点解析
-
使用 :where() 构建动态选择器
利用现代 CSS 的 :where() 伪类(兼容 Chrome 105+、Firefox 103+、Safari 15.4+),可安全组合多个类名而无需担心优先级干扰:let productSelector = '.product'; if (selectedCategories.length !== 0) { productSelector += ':where(.' + selectedCategories.join(', .') + ')'; }例如勾选 “salty” 和 “sweet” 时,生成选择器 .product:where(.salty, .sweet),精准匹配所有带任一目标类的元素。
-
分离「过滤状态」与「DOM 操作」
不再直接修改 style.display,而是统一通过 CSS 类 filtered 控制显隐:.product.filtered { display: none; }这样更易维护,且避免内联样式覆盖风险。
-
动态维护 filteredProducts 数据源
每次筛选后,立即执行:filteredProducts = document.querySelectorAll(productSelector);
后续所有分页计算(总页数、当前页边界、按钮禁用状态)均基于此真实筛选结果集,而非原始 products。
-
智能重置当前页码
防止用户筛选后停留在超出新数据范围的页码(如原第 5 页,筛选后只剩 2 页):currentPage = Math.min(currentPage, Math.ceil(filteredProducts.length / productsPerPage));
✅ 完整可运行代码(含 HTML/CSS/JS)
<!-- HTML 结构(保持不变,仅需添加 .filtered 类支持) --> <h1>Food Catering Menu</h1> <!-- ... 分类复选框 ... --> <div class="products"> <!-- 所有 .product 元素(同原示例) --> </div> <div class="pagination"> <button id="prevPage">Previous Page</button> <button id="nextPage">Next Page</button> </div>
/* CSS 样式 */
.product {
display: block;
margin: 8px 0;
padding: 10px;
border: 1px solid #eee;
border-radius: 4px;
}
.product.filtered {
display: none;
}
.pagination {
margin-top: 20px;
}
// JavaScript 逻辑(推荐置于










