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

添加<form>标签后触发Uncaught TypeError: lineTotal is not a function错误求助

问题:添加<form>后JavaScript自动计算功能失效,报错lineTotal is not a function

问题描述

原有JavaScript代码可实现添加表格行、自动计算金额与数量并展示在lineTotal列等功能,运行正常。但为代码添加<form>标签后,自动计算功能失效,控制台抛出Uncaught TypeError: lineTotal is not a function错误——虽然使用console.log(lineTotal)可正常输出该函数,但触发onblur事件时无法识别函数。

相关代码

JavaScript代码

var renumber = 0;

function calculateDueAmount() {
  var tblRows = document.getElementById("addItems").getElementsByTagName("tr");
  let total = 0;
  for (var i = 0; i < tblRows.length; i++) {
    let lineTotal = tblRows[i]
      .getElementsByTagName("td")[4]
      .getElementsByTagName("input")[0].value;
    total += Number(lineTotal);
  }
  document.getElementById("amountDue").innerText = total.toFixed(2);
}

function addItem() {
  renumber++;
  var html = "<tr>";
  html += "<td id='itemNum'>" + renumber + "</td>";
  html += "<td><input name='itemName[]'></td>";

  html +=
    "<td><span class='currency'>$</span><input  onblur='lineTotal(this);' value='0' name='amount[]'></td>";
  html +=
    "<td><input  onblur='lineTotal(this);' value='0' name='qty[]'></td>";
  html +=
    "<td><span class='currency'>$</span><input onblur='lineTotal(this);' value='0' name='lineTotal[]'></td>";
  html +=
    "<td><button type='button' id='remove_button' onclick='removeItem(this);'> X </button></td>";
  html += "</tr>";
  document.getElementById("addItems").insertRow().innerHTML = html;
}

function removeItem(elem) {
  let rowToDelete = elem.parentElement.parentElement;
  let rowNumber = rowToDelete.getElementsByTagName("td")[0].innerText;
  document.getElementById("addItems").deleteRow(rowNumber - 1);
  let tblRows = document.getElementById("addItems").getElementsByTagName("tr");
  let j = 0;
  for (; j < tblRows.length; j++) {
    tblRows[j].getElementsByTagName("td")[0].innerText = j + 1;
  }
  calculateDueAmount();
  renumber = j;
}

function lineTotal(elem) {
  var mainRow = elem.parentElement.parentElement;
  var amt = mainRow
    .getElementsByTagName("td")[2]
    .getElementsByTagName("input")[0].value;
  var qty = mainRow
    .getElementsByTagName("td")[3]
    .getElementsByTagName("input")[0].value;
  var total = mainRow
    .getElementsByTagName("td")[4]
    .getElementsByTagName("input")[0];
  var myResult = Number(amt) * Number(qty);
  total.value = myResult;
  calculateDueAmount();
}

HTML代码

<div class="home-section">
  <div class="sign-up-box">
    <h1>Payment details</h1>

    <div class="signup-container">
      <label>Service Ticket Number : </label>
      <br />

      <form action="" method="post">
        <table>
          <tr>
            <th>#</th>
            <th>Item Name</th>

            <th>Amount per unit</th>
            <th>Quantity</th>
            <th>Line Total</th>
          </tr>

          <tbody id="addItems"></tbody>
        </table>

        <p>
          <button type="button" onclick="addItem();">Add Item</button>
        </p>

        <p>
          Amount Due: $<span id="amountDue">0.00</span>
          <script src="includes/javascript.js"></script>
        </p>

        <p>
          <input id="invoice_submit" type="submit" name="submit" />
        </p>
      </form>
    </div>
  </div>
</div>

解决方案

问题根源

在<form>标签内部,表单元素的name属性会被挂载为表单对象的属性。你的代码中,lineTotal列的input元素设置了name="lineTotal[]",这导致在表单上下文里,lineTotal指向的是该表单元素的集合,而非你定义的全局函数,因此触发onblur='lineTotal(this);'时会抛出类型错误。

解决办法(任选其一)

  1. 修改函数名称
    将lineTotal函数重命名为不与表单元素name冲突的名称(比如calculateLineTotal),同时更新所有调用该函数的地方:

    // 修改函数名
    function calculateLineTotal(elem) {
      var mainRow = elem.parentElement.parentElement;
      var amt = mainRow.getElementsByTagName("td")[2].getElementsByTagName("input")[0].value;
      var qty = mainRow.getElementsByTagName("td")[3].getElementsByTagName("input")[0].value;
      var total = mainRow.getElementsByTagName("td")[4].getElementsByTagName("input")[0];
      var myResult = Number(amt) * Number(qty);
      total.value = myResult;
      calculateDueAmount();
    }
    

    对应HTML中的调用修改为:

    <td><span class='currency'>$</span><input onblur='calculateLineTotal(this);' value='0' name='amount[]'></td>
    <td><input onblur='calculateLineTotal(this);' value='0' name='qty[]'></td>
    <td><span class='currency'>$</span><input onblur='calculateLineTotal(this);' value='0' name='lineTotal[]'></td>
    
  2. 强制调用全局函数
    在onblur事件中明确指定调用全局作用域下的lineTotal函数,避免被表单元素的name覆盖:

    <td><span class='currency'>$</span><input onblur='window.lineTotal(this);' value='0' name='amount[]'></td>
    <td><input onblur='window.lineTotal(this);' value='0' name='qty[]'></td>
    <td><span class='currency'>$</span><input onblur='window.lineTotal(this);' value='0' name='lineTotal[]'></td>
    
  3. 修改表单元素的name属性
    将lineTotal列的input元素name改为其他值(比如line_total[]),消除与函数名的冲突:

    <td><span class='currency'>$</span><input onblur='lineTotal(this);' value='0' name='line_total[]'></td>
    

    此方法无需修改函数代码,仅需调整HTML中的name属性即可。


内容的提问来源于stack exchange,提问作者noinput25

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 20:25:25