jQuery实现嵌套表格父子tr复选框checked状态双向联动
嵌套表格父子行复选框联动实现
需求说明
开发含父子行结构的嵌套表格,需实现复选框双向联动:
- 点击父行复选框时,其下所有子行复选框同步切换为和父行一致的选中状态
- 手动勾选/取消子行复选框时:只要当前父行下存在任意1个选中的子项,父行自动选中;如果所有子项全部取消选中,父行同步取消选中
原有代码问题
- 重复定义id:DOM规范要求id全局唯一,原有代码多组父/子行复用了
parent-tr、child-tr等同名id,会导致选择器匹配异常 - 未绑定交互事件:原有逻辑仅在页面初始化时执行1次,用户点击复选框时不会触发联动计算
- 父子行匹配逻辑错误:靠索引值匹配父子行,DOM顺序变动时会出现关联错误,应该用行上自带的
data-id、data-subject-id属性做精准关联 - 状态操作API错误:使用
attr()设置复选框选中状态,该方法仅能修改初始属性,动态交互时状态不会同步更新,应该用prop()操作表单元素的实时状态
完整实现代码
首先修正HTML的重复id问题(移除重复的id属性,保留class作为选择器即可):
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table class="table"> <tbody> <!-- BEGIN::Subject loop --> <tr class="parent-tr" data-id="2"> <td class="action"> <input type="checkbox" name="checkbox[2]" value="2"> </td> </tr> <!-- END::Subject loop --> <!-- BEGIN::Tickers loop --> <tr class="child-tr" data-ticker-id="6" data-subject-id="2"> <td class="action"> <input type="checkbox" name="tikcer"> </td> </tr> <tr class="child-tr" data-ticker-id="7" data-subject-id="2"> <td class="action"> <input type="checkbox" name="tikcer"> </td> </tr> <tr class="child-tr" data-ticker-id="8" data-subject-id="2"> <td class="action"> <input type="checkbox" name="tikcer"> </td> </tr> <!-- END::Tickers loop --> <!-- BEGIN::Subject loop --> <tr class="parent-tr" data-id="3"> <td class="action"> <input type="checkbox" name="checkbox[3]" value="3"> </td> <td colspan="6"></td> </tr> <!-- END::Subject loop --> <!-- BEGIN::Tickers loop --> <tr class="child-tr" data-ticker-id="9" data-subject-id="3"> <td class="action"> <input type="checkbox" name="tikcer"> </td> </tr> <tr class="child-tr" data-ticker-id="10" data-subject-id="3"> <td class="action"> <input type="checkbox" name="tikcer"> </td> </tr> <tr class="child-tr" data-ticker-id="11" data-subject-id="3"> <td class="action"> <input type="checkbox" name="tikcer"> </td> </tr> <!-- END::Tickers loop --> </tbody> </table>
注:原有子行复选框的
name="tikcer"疑似拼写错误(正确应为ticker),如果是业务自定义字段可忽略。
JS联动逻辑代码:
$(function() { // 父行复选框点击:联动所有对应子行状态 $(document).on('change', '.parent-tr input:checkbox', function() { const isChecked = $(this).prop('checked'); const parentId = $(this).closest('.parent-tr').data('id'); // 匹配所有归属当前父行的子行,同步选中状态 $(`.child-tr[data-subject-id="${parentId}"] input:checkbox`).prop('checked', isChecked); }) // 子行复选框点击:联动对应父行状态 $(document).on('change', '.child-tr input:checkbox', function() { const subjectId = $(this).closest('.child-tr').data('subject-id'); const $parentCheckbox = $(`.parent-tr[data-id="${subjectId}"] input:checkbox`); // 统计当前父行下已选中的子项数量 const checkedChildCount = $(`.child-tr[data-subject-id="${subjectId}"] input:checkbox:checked`).length; // 存在选中子项则父行选中,否则取消选中 $parentCheckbox.prop('checked', checkedChildCount > 0); }) })
逻辑说明
- 用事件委托绑定
change事件,后续动态新增的父子行也能自动生效,不需要重复绑定事件 - 父子行通过
data-id和data-subject-id做精准匹配,不会因为DOM顺序变化出现关联错误 - 全部用
prop()操作复选框的checked状态,保证交互时状态实时同步 - 子行联动父行时通过统计选中子项数量判断父行状态,覆盖全选、部分选、全不选所有场景
内容的提问来源于stack exchange,提问作者afi
相关产品推荐
相关产品推荐

