HTML表格Yes/No响应百分比、月度及总平均计算(解决NaN%问题)
代码问题定位
- 函数重复定义冲突:代码中两次书写完全同名的
count_yes_no函数,后定义的逻辑会完全覆盖前者,且所有月份的计算函数都固定指向#span1这个非法DOM节点,没有做月份维度的DOM匹配,计算逻辑无法触达对应月份的下拉选择框 - DOM结构不符合规范:
<span id="span1">直接嵌套在<tr>标签下,浏览器渲染时会自动修正DOM结构,导致脚本无法正确读取节点内的下拉框值,计算时分母为0,最终输出NaN% - 全局类名冲突:所有月份的百分比展示span都使用同一个类名
cnt-percent-y,脚本更新时会同步修改所有同标签的内容,导致各月份的计算结果完全一致 - 逻辑缺失:没有覆盖全部12个月份的独立计算触发逻辑,也没有实现全局总平均值的汇总计算流程
修复后完整实现
基础样式
table { font-family: arial, sans-serif; border-collapse: collapse; width: 100%; } td, th { border: 1px solid #dddddd; text-align: left; padding: 8px; } tr:nth-child(even) { background-color: #dddddd; }
结构调整后的HTML
<h1>作答平均百分比统计</h1> <table> <thead> <tr> <th>问题项</th> <th>1月</th> <th>2月</th> <th>3月</th> <th>4月</th> <th>5月</th> <th>6月</th> <th>7月</th> <th>8月</th> <th>9月</th> <th>10月</th> <th>11月</th> <th>12月</th> <th>总平均</th> </tr> </thead> <tbody> <tr> <td>储蓄</td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> </tr> <tr> <td>超预算</td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> <td><select onchange="recalcAll()"><option value="Yes">是</option><option value="No">否</option></select></td> </tr> </tbody> <tfoot> <tr> <td>作答百分比</td> <td><span id="month-percent-1">0</span>%</td> <td><span id="month-percent-2">0</span>%</td> <td><span id="month-percent-3">0</span>%</td> <td><span id="month-percent-4">0</span>%</td> <td><span id="month-percent-5">0</span>%</td> <td><span id="month-percent-6">0</span>%</td> <td><span id="month-percent-7">0</span>%</td> <td><span id="month-percent-8">0</span>%</td> <td><span id="month-percent-9">0</span>%</td> <td><span id="month-percent-10">0</span>%</td> <td><span id="month-percent-11">0</span>%</td> <td><span id="month-percent-12">0</span>%</td> <td><span id="total-average">0</span>%</td> </tr> </tfoot> </table>
重构后的JavaScript逻辑
// 页面加载完成后自动触发首次计算 window.onload = function() { recalcAll(); } function recalcAll() { const totalMonths = 12; const questionsPerMonth = 2; // 每个月对应储蓄、超预算2道题 let allMonthPercentSum = 0; // 遍历每个月份做独立计算 for (let monthIdx = 1; monthIdx <= totalMonths; monthIdx++) { let yesCount = 0; // 获取当前月份列的所有下拉框 const monthSelects = document.querySelectorAll(`tbody tr td:nth-child(${monthIdx + 1}) select`); monthSelects.forEach(select => { if (select.value === 'Yes') yesCount++; }); // 计算当月百分比,增加分母判断避免NaN错误 const monthPercent = questionsPerMonth > 0 ? (yesCount / questionsPerMonth) * 100 : 0; // 展示当月百分比 document.getElementById(`month-percent-${monthIdx}`).textContent = monthPercent.toFixed(0); // 累加所有月份的百分比用于计算全局总平均 allMonthPercentSum += monthPercent; } // 计算全局总平均值 const totalAvg = totalMonths > 0 ? allMonthPercentSum / totalMonths : 0; document.getElementById('total-average').textContent = totalAvg.toFixed(0); }
计算规则匹配需求示例:1月储蓄选No、超预算选Yes时,Yes计数为1,当月百分比为(1/2)*100=50%,和预期效果一致。
内容的提问来源于stack exchange,提问作者CruzzerK97
相关产品推荐
相关产品推荐

