You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 15:06:01