表格多行显示/隐藏实现:按类筛选并保留奇偶行CSS样式
刚好碰到过类似的需求,给你一套完整的实现方案,既能搞定多条件筛选,还能保证筛选后的奇偶行斑马纹正常显示,一步到位:
实现步骤
1. 搭建HTML结构
先把筛选按钮和表格的基础结构写好,给每个筛选按钮加个统一的类filter-btn,再用data-target属性绑定对应的行class,后续扩展选项会很方便:
<div class="filter-controls"> <label><input type="checkbox" class="filter-btn" data-target="option1"> 显示Option1行</label> <label><input type="checkbox" class="filter-btn" data-target="option2"> 显示Option2行</label> <label><input type="checkbox" class="filter-btn" data-target="option3"> 显示Option3行</label> </div> <table id="data-table"> <thead> <tr> <th>列1</th> <th>列2</th> <th>列3</th> </tr> </thead> <tbody> <tr class="option1"><td>Option1 行1</td><td>测试内容</td><td>测试内容</td></tr> <tr class="option2"><td>Option2 行1</td><td>测试内容</td><td>测试内容</td></tr> <tr class="option1"><td>Option1 行2</td><td>测试内容</td><td>测试内容</td></tr> <tr class="option3"><td>Option3 行1</td><td>测试内容</td><td>测试内容</td></tr> <tr class="option2"><td>Option2 行2</td><td>测试内容</td><td>测试内容</td></tr> <tr class="option1"><td>Option1 行3</td><td>测试内容</td><td>测试内容</td></tr> </tbody> </table>
2. 编写CSS样式
这里要注意:原生的tr:nth-child(odd/even)是根据父元素的所有子元素排序,不管行是否隐藏,筛选后斑马纹会乱。所以我们改用自定义的.odd和.even类来控制,同时默认隐藏所有行,由JS来控制显示:
/* 默认隐藏所有表格行 */ #data-table tbody tr { display: none; } /* 自定义斑马纹样式 */ #data-table tbody tr.odd { background-color: #f5f5f5; } #data-table tbody tr.even { background-color: #ffffff; }
3. 实现JavaScript逻辑
核心做两件事:监听复选框变化筛选行,筛选完成后重新给可见行分配奇偶类,保证斑马纹正常:
// 获取页面元素 const filterButtons = document.querySelectorAll('.filter-btn'); const tableRows = document.querySelectorAll('#data-table tbody tr'); // 筛选行的核心函数 function filterRows() { // 收集所有选中的目标class const selectedClasses = Array.from(filterButtons) .filter(btn => btn.checked) .map(btn => btn.dataset.target); // 遍历所有行,判断是否显示 tableRows.forEach(row => { // 如果没有选中任何按钮,默认显示所有行;否则判断行是否包含选中的class const shouldDisplay = selectedClasses.length === 0 || selectedClasses.some(cls => row.classList.contains(cls)); row.style.display = shouldDisplay ? 'table-row' : 'none'; }); // 筛选完成后更新斑马纹 updateZebraStripes(); } // 更新斑马纹的函数 function updateZebraStripes() { // 获取所有可见的行 const visibleRows = Array.from(tableRows).filter(row => row.style.display !== 'none'); // 给可见行重新分配奇偶类 visibleRows.forEach((row, index) => { row.classList.remove('odd', 'even'); row.classList.add(index % 2 === 0 ? 'odd' : 'even'); }); } // 给每个复选框绑定变化事件 filterButtons.forEach(btn => { btn.addEventListener('change', filterRows); }); // 页面加载时默认执行一次筛选(如果需要默认全选,可以给按钮加checked属性) filterRows();
几个关键细节说明
- 用
data-target绑定按钮和行class,后续新增选项只需要加按钮和对应行的class,不用修改JS逻辑,扩展性很强 - 当没有选中任何复选框时,默认显示所有行,你可以根据需求改成隐藏所有,只需要调整
shouldDisplay的判断条件 - 筛选后通过
updateZebraStripes重新计算可见行的奇偶顺序,完美解决原生伪类不识别隐藏元素的问题 - 所有行默认隐藏,由JS控制显示,比一开始全显示再隐藏的性能更好
内容的提问来源于stack exchange,提问作者MAlgol
相关产品推荐
相关产品推荐

