添加<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);'时会抛出类型错误。
解决办法(任选其一)
修改函数名称
将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>强制调用全局函数
在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>修改表单元素的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
相关产品推荐
相关产品推荐

