如何通过ID获取复选框,避免重复类与函数实现表格列显隐切换?
问题
我通过表格上方的复选框(ID为product_1、product_2等)切换表格的类来隐藏指定列,表格共4列,因此写了4个重复的JS函数:
const toggleFirst = document.getElementById('product_1').addEventListener('click', () => { document.querySelector('#compare-table').classList.toggle('tb-compare-hide-1'); }); const toggleSecond = document.getElementById('product_2').addEventListener('click', () => { document.querySelector('#compare-table').classList.toggle('tb-compare-hide-2'); }); const toggleThird = document.getElementById('product_3').addEventListener('click', () => { document.querySelector('#compare-table').classList.toggle('tb-compare-hide-3'); }); const toggleFourth = document.getElementById('product_4').addEventListener('click', () => { document.querySelector('#compare-table').classList.toggle('tb-compare-hide-4'); });
切换的类用于控制列的显示与隐藏,当前功能正常,但存在4个重复的CSS类和JS函数,仅关联的复选框与类不同。请问能否用更少的重复类和函数实现该功能?
优化方案
一、简化JavaScript代码
无需编写4个重复的监听函数,用通用逻辑即可实现,推荐两种方式:
方式1:从复选框ID提取列编号
利用ID的命名规则(product_数字)提取对应列编号,动态生成类名:
const checkboxes = document.querySelectorAll('[id^="product_"]'); const table = document.querySelector('#compare-table'); checkboxes.forEach(checkbox => { checkbox.addEventListener('click', () => { const columnNum = checkbox.id.split('_')[1]; table.classList.toggle(`tb-compare-hide-${columnNum}`); }); });
方式2:用data属性绑定列编号(更灵活)
给每个复选框添加data-column属性,摆脱对ID命名的依赖:
<!-- 修改复选框HTML,添加data-column属性 --> <input type="checkbox" id="product_1" data-column="1"> <input type="checkbox" id="product_2" data-column="2"> <input type="checkbox" id="product_3" data-column="3"> <input type="checkbox" id="product_4" data-column="4">
对应的JS代码简化为:
const checkboxes = document.querySelectorAll('[data-column]'); const table = document.querySelector('#compare-table'); checkboxes.forEach(checkbox => { checkbox.addEventListener('click', () => { const columnNum = checkbox.dataset.column; table.classList.toggle(`tb-compare-hide-${columnNum}`); }); });
二、简化CSS代码
如果你的CSS是重复编写4个结构一致的类,可通过以下方式减少重复:
原生CSS简化
用属性选择器匹配类名前缀,整合重复规则:
#compare-table[class*="tb-compare-hide-"] { &.tb-compare-hide-1 th:nth-child(1), &.tb-compare-hide-1 td:nth-child(1), &.tb-compare-hide-2 th:nth-child(2), &.tb-compare-hide-2 td:nth-child(2), &.tb-compare-hide-3 th:nth-child(3), &.tb-compare-hide-3 td:nth-child(3), &.tb-compare-hide-4 th:nth-child(4), &.tb-compare-hide-4 td:nth-child(4) { display: none; } }
结构更清晰,后续新增列只需补充对应nth-child规则即可。
用Sass/LESS循环彻底消除重复(推荐)
如果项目使用CSS预处理器,可通过循环自动生成所有列的隐藏规则:
@columns: 4; // 列总数 #compare-table { @for $i from 1 through @columns { &.tb-compare-hide-#{$i} { th:nth-child(#{$i}), td:nth-child(#{$i}) { display: none; } } } }
编译后会自动生成对应数量的CSS类规则,无需手动重复编写。
进阶方案:无需多个CSS类
直接通过JS控制列的显示状态,完全消除CSS类的重复:
const checkboxes = document.querySelectorAll('[data-column]'); const table = document.querySelector('#compare-table'); // 初始化列显示状态 checkboxes.forEach(updateColumnVisibility); // 监听复选框变化 checkboxes.forEach(checkbox => { checkbox.addEventListener('change', () => updateColumnVisibility(checkbox)); }); // 通用更新函数 function updateColumnVisibility(checkbox) { const columnNum = checkbox.dataset.column; const columns = table.querySelectorAll(`th:nth-child(${columnNum}), td:nth-child(${columnNum})`); columns.forEach(el => { el.style.display = checkbox.checked ? 'none' : ''; }); }
这种方式无需额外CSS类,直接通过JS操作元素样式,代码更简洁。
内容的提问来源于stack exchange,提问作者nilemonster
相关产品推荐
相关产品推荐

