能否使用单个jQuery循环替代input与td的两个循环实现相同功能?
能否用单个循环替代jQuery中的两个元素处理循环?
问题描述
我当前的jQuery代码中使用了两个循环,分别处理input元素和td元素,想知道是否可以仅用单个循环实现完全相同的功能。相关代码如下:
原jQuery代码
$("#bodyTargets tr").filter(function(index) { const firstTdText = Number($(this).find("td:first").text()) || 0; return !(firstTdText >= (Number($txtStartMonth.val()) || 0) && firstTdText <= (Number($txtEndMonth.val()) || 0)); }).each(function(index, element) { $(this).find("input").each(function() { $(this).prop("disabled", true); $(this).css('color', 'red'); }); $(this).find("td").each(function() { $(this).css('color', 'red'); }); });
对应HTML结构
<table class="table table-borderless table-sm"> <thead id="headTargets"> <tr> <th width="80px">Period</th> <th width="150px">Month</th> <th width="80px">Status</th> <th width="100px">Actual Value</th> <th width="100px">Initial Target</th> <th></th> </tr> </thead> <tbody id="bodyTargets"> <tr id="trDataPoint_23139687" data-recordid="23139687"> <td id="tdProjectMonth_23139687">15</td> <td id="tdCalendarMonth_23139687">2024 - March</td> <td id="tdStatusL3_23139687">Pending</td> <td width="100px"><input class="form-control target-form" data-recordid="23139687" data-oldvalue="" id="txtActualValue_23139687" data-prevrecordid="" value=""></td> <td width="100px"><input class="form-control target-form" data-recordid="23139687" data-oldvalue="" id="txtInitialTarget_23139687" data-prevrecordid="" value=""></td> <td></td> </tr> <tr id="trDataPoint_23139688" data-recordid="23139688"> <td id="tdProjectMonth_23139688">16</td> <td id="tdCalendarMonth_23139688">2024 - April</td> <td id="tdStatusL3_23139688">Pending</td> <td width="100px"><input class="form-control target-form" data-recordid="23139688" data-oldvalue="" id="txtActualValue_23139688" data-prevrecordid="txtActualValue_23139687" value=""></td> <td width="100px"><input class="form-control target-form" data-recordid="23139688" data-oldvalue="" id="txtInitialTarget_23139688" data-prevrecordid="txtInitialTarget_23139687" value=""></td> <td></td> </tr> </tbody> </table>
解决方案
当然可以,有两种更简洁的实现方式:
方式一:合并选择器,使用单个循环
通过将input和td选择器合并,在同一个循环里根据元素类型处理不同逻辑,既减少了循环次数,又实现了相同效果:
$("#bodyTargets tr").filter(function(index) { const firstTdText = Number($(this).find("td:first").text()) || 0; return !(firstTdText >= (Number($txtStartMonth.val()) || 0) && firstTdText <= (Number($txtEndMonth.val()) || 0)); }).each(function(index, element) { // 合并选择器,用单个循环处理input和td $(this).find("input, td").each(function() { const $elem = $(this); // 仅对input元素设置disabled属性 if ($elem.is("input")) { $elem.prop("disabled", true); } // 给所有选中元素设置文字颜色 $elem.css('color', 'red'); }); });
方式二:使用CSS类优化(更推荐)
直接操作样式的维护性较差,更优雅的做法是定义CSS类,通过添加/移除类来实现样式变化,同时单独处理input的disabled属性,这种方式甚至不需要循环遍历每个元素:
首先添加CSS样式:
.disabled-row { color: red; } .disabled-row input { color: red; background-color: #f5f5f5; /* 可选:添加背景色增强禁用视觉效果 */ }
然后修改jQuery代码:
$("#bodyTargets tr").filter(function(index) { const firstTdText = Number($(this).find("td:first").text()) || 0; return !(firstTdText >= (Number($txtStartMonth.val()) || 0) && firstTdText <= (Number($txtEndMonth.val()) || 0)); }).each(function(index, element) { // 给tr添加类,自动应用td和input的样式 $(this).addClass('disabled-row') // 单独设置input的disabled属性 .find('input').prop('disabled', true); });
这种方式代码更简洁,样式和逻辑分离,后期维护也更方便。
内容的提问来源于stack exchange,提问作者Karim Ali
相关产品推荐
相关产品推荐

