使用JavaScript实现动态表格年月差自动计算的问题咨询
问题原因
- 选择器使用错误:
$('#from[]')不是合法的jQuery属性选择器,无法匹配到name为from[]的输入框 - 未使用事件委托:动态新增的行元素无法被提前绑定的change事件监听到
- 元素ID硬编码:每行的输入框ID都是
from+序号/to+序号/duration+序号,原代码硬写from0/to/duration无法匹配对应行的输入框 - 日期计算逻辑错误:逗号运算符
(start, end)不会计算差值,仅会返回最后一个值,没有实现年月差的计算逻辑 - 语法错误:JS代码末尾多了冗余的
});,会导致代码运行报错
修正后的完整代码
JavaScript部分
<script src="https://code.jquery.com/jquery-3.5.0.js"></script> <script type="text/javascript"> var h = 0; function history() { h++; var copyContent= "<tr><td><input class='tableBody month-input from' type='month' id='from"+h+"' name='from[]' autocomplete='off' required></td>"; copyContent += "<td><input class='tableBody month-input to' type='month' id='to"+h+"' name='to[]' autocomplete='off' required></td>"; copyContent += "<td><input class='tableBody duration' type='text' id='duration"+h+"' name='duration[]' autocomplete='off' required></td>"; copyContent += "<td><input class='tableBody' type='text' name='reason[]' autocomplete='off' required /></td>"; copyContent += "<td><input class='tableBody' type='text' name='other[]' autocomplete='off' required /></td>"; copyContent += "<td><a href='javascript:void(0);' class='remove' style='cursor:pointer'><i class='material-icons' title='Delete item'>remove_circle_outline</i></a></td></tr>"; $('#tbl_history').append(copyContent); document.getElementById("h").value = h; } // 事件委托绑定年月输入框变化事件,兼容动态新增行 $('#tbl_history').on('change', '.month-input', function() { // 获取当前行 const $row = $(this).closest('tr'); const fromVal = $row.find('.from').val(); const toVal = $row.find('.to').val(); // 两个值都选了才计算 if (!fromVal || !toVal) return; // 拆分年月 const [fromYear, fromMonth] = fromVal.split('-').map(Number); const [toYear, toMonth] = toVal.split('-').map(Number); // 计算月份差,加1是首尾月都计算,不需要可以直接去掉+1 let monthDiff = (toYear - fromYear) * 12 + (toMonth - fromMonth) + 1; // 处理结束时间早于开始时间的异常情况 monthDiff = monthDiff < 0 ? 0 : monthDiff; // 赋值到时长输入框,格式可自定义调整 let durationText = ''; if (monthDiff >= 12) { const year = Math.floor(monthDiff / 12); const month = monthDiff % 12; durationText = year + '年' + (month > 0 ? month + '个月' : ''); } else { durationText = monthDiff + '个月'; } $row.find('.duration').val(durationText); // 可选:限制结束时间最小为选择的开始时间 $row.find('.to').attr('min', fromVal); }); // 绑定删除行功能 $('#tbl_history').on('click', '.remove', function() { $(this).closest('tr').remove(); // 如需同步更新行号计数器可开启下面两行 // h = $('#tbl_history tr').length - 2; // document.getElementById("h").value = h; }); </script>
HTML部分(修复标签未闭合、非法嵌套问题)
<table id="tbl_history" style="margin-top:25px;margin-bottom:25px;"> <tr class="tableTitle"> <th><center>From</center></th> <th><center>To</center></th> <th style="width:150px;"><center>Duration</center></th> <th><center>Reason</center></th> <th><center>Other</center></th> </tr> <tr> <td><input class="tableBody month-input from" type="month" id="from0" name="from[]" autocomplete="off" required></td> <td><input class="tableBody month-input to" type="month" id="to0" name="to[]" autocomplete="off" required></td> <td><input class="tableBody duration" type="text" id="duration0" name="duration[]" autocomplete="off" required></td> <td><input class='tableBody' type='text' name='reason[]' autocomplete='off' required /></td> <td><input class='tableBody' type='text' name='other[]' autocomplete='off' required /></td> </tr> </table> <div style="margin-right:-1200px"> <a onclick="history()" style="cursor:pointer"><i class="material-icons" title="Add item">add_circle_outline</i></a> </div> <input name="h" type="text" id="h" readonly hidden>
内容的提问来源于stack exchange,提问作者gammer
相关产品推荐
相关产品推荐

