我正在寻找一些代码的帮助。我应该创建一个表单,允许用户输入他们想要购买的商品的数量。输入数量时,将显示该特定项目的总价格,以及所有购买的总计(在表格底部)。当用户按下提交按钮时,会出现警告弹出窗口。
我在javascript中遇到了计算部分的问题。它不计算任何总量或数量值。 (由于某种原因,代码不会在这里正确缩进,但它们在实际文档中)。
function calc(){
var QtyA = 0; var QtyB = 0; var QtyC = 0;
var TotA = 0; var TotB = 0; var TotC = 0;
var PrcA = 3; var PrcB = 4; var PrcC = 5.50;
if (document.getElementById('QtyA').value > "");{
QtyA = document.getElementById('QtyA').value;}
TotA = eval(QtyA) * eval(PrcA);
TotA = TotA.toFixed(2);
(document.getElementById('TotalA').value = TotA);
if (document.getElementById('QtyB').value > "");{
QtyB = document.getElementById('QtyB')value;}
TotB = eval(QtyB) * eval(PrcB);
TotB = TotB.toFixed(2);
(document.getElementById('TotalB').value = TotB);
if (document.getElementById('QtyC').value > "");{
QtyC = document.getElementById('QtyC')value;}
TotC = eval(QtyC) * eval(PrcC);
TotC = TotC.toFixed(2);
(document.getElementById('TotalC')value = TotC);
Totamt = eval(TotA) + eval(TotB) + eval(TotC);
Totamt = Totamt.toFixed(2); //fix to 2 decimal places
(document.getElementById('Grand Total is: ').value = Totamt);
alert (Totamt);
<html>
<head>
<meta charset="UTF-8">
<title>Order Form</title>
<style>
@import "css/OrderForm.css";
</style>
<body>
<form>
<table border="1">
<tr>
<th>Item</th>
<th>Image</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
<tr>
<td width="80">Hat</td>
<td><img src="images/hat.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA" size="5" onchange "calc()"></td>
<td>€3.00</td>
<td>
<input type="text" id="TotalA" size="12" onchange "calc()">
</td>
</tr>
<tr>
<td width="80">T Shirt</td>
<td><img src="images/t_shirt.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA" size="5" onchange "calc()"></td>
<td>€4.00</td>
<td>
<input type="text" id="TotalA" size="12" onchange "calc()">
</td>
</tr>
<tr>
<td width="80">Glasses</td>
<td><img src="images/glasses.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA" size="5" onchange "calc()"></td>
<td>€5.50</td>
<td>
<input type="text" id="TotalA" size="12" onchange "calc()">
</td>
</tr>
<tr>
<td> Total: </td>
<td><input type="text" id="GrandTotal" size="15" onchange="calc()"></td>
</tr>
</table>
<input type="submit" value="Submit">
<input type="reset" value="Reset">
</form>
</body>
</html>
好吧,作为一名教师,我不能让所有人试图教你的坏习惯。那么,我们走吧......
eval()
是邪恶的 - 永远不要使用它!
eval()
告诉JavaScript运行时处理字符串就像它是JavaScript一样。这是非常危险的,因为如果字符串包含恶意代码,eval()
将运行它。在你的代码中,你在eval()
上运行value
进入一个文本框,因为你不知道将输入什么值,你也不知道eval()
将接收什么字符串。这相当于一个巨大的安全漏洞,这是不应该使用eval()
的原因之一。其次,即使在完美的世界中,eval()
也很慢,所以从纯粹的表演角度来看,你不会想要使用它。坦率地说,有人教你使用它,尤其是将字符串转换为数字时,我感到很震惊。仅此一点就足以要求退款了!
在您的情况下,您需要将字符串输入转换为数字,以便您可以使用输入进行数学运算。 JavaScript提供了几种方法:
parseInt(stringContainingNumber, radix)
parseFloat(stringContainingNumber)
Number(stringContainingNumber)
+stringThatIsNumber
Unary Operator不要使用事件属性在HTML中设置事件处理。当JavaScript首次创建(25年前)时,为HTML元素(也称为DOM元素)设置事件处理程序的方法是使用onclick
,onchange
,onmouseover
等HTML属性内嵌元素。 HTML。不幸的是,由于这种技术看起来多么简单,它会被反复使用而不是死于它应得的快速死亡。有several reasons not to use this outdated technique。今天,我们要遵循现代标准和最佳实践,因此,事件处理应该使用JavaScript,与HTML分开,使用.addEventListener()
此外,您的代码:onchange "calc()"
无论如何都是错误的,因为代码应该是:onchange = "calc()"
。
另外,考虑哪些元素需要为它们设置事件。您的原始代码已设置好,如果总数发生变化,calc()
会运行,但这没有任何意义。为什么有人能够直接改变总数,实际上会发生什么呢?数量是否会因为总数发生变化而发生变化?
注意细节你有3行计算3个数量* 3个价格得到3个总计,但你只是复制/粘贴了3行的HTML并且用3个输入元素和id
相同的QtyA
,即使你的JavaScript是正确地寻找QtyB
和QtyC
。
使用CSS而不是HTML进行样式化所有数量输入字段都需要将其宽度设置为5.不要使用HTML size
属性,使用width
CSS属性。 HTML将更清晰,您不必重复相同的指令3次。
@import使用不正确CSS @import指令用作外部样式表中的第一行,它从另一个样式表导入指令,有效地将多个表合并为一个。如果您只使用一个样式表,则不会导入它,而是链接到它。
而不是:<style> @import "css/OrderForm.css";</style>
使用:<link href="css/OrderForm.css" rel="stylesheet">
当您只是显示结果时,请不要将其放在表单域中。当您不希望用户能够修改该结果时,没有理由将总数放入input
字段。相反,只需将其作为不可编辑元素的文本 - 在您的情况下,将表格放在适当的单元格中。
最后:使用开发人员的工具!所有现代浏览器都包含“开发人员工具”,您可以通过按F12激活它们。工具中有许多选项卡,但“控制台”选项卡可能对您来说最重要。如果您的语法有错误(就像您一样),控制台将显示它们和行号。您必须先消除所有语法错误,然后才能运行代码。
控制台也是用于在代码中测试值的宝贵工具。你可以插入:
console.log(anything that is supposed to produce a value);
在您的代码中验证变量,元素等是否具有您认为它们所执行的值。
现在,实际上,我会以一种与你正在尝试的方式完全不同的方式来解决这个问题,但这比你在这个阶段做好准备要复杂得多,所以我已经采用了你的方法。
请仔细阅读HTML和JavaScript注释,以解释正在做什么。
<!DOCTYPE html> <!-- The DOCTYPE tells the browser what version of HTML it should be expecting. -->
<html>
<head>
<meta charset="UTF-8">
<title>Order Form</title>
<!-- To reference a single stylesheet, use the link element: -->
<link href="css/OrderForm.css" rel="stylesheet">
<style>
/* Make all the input elements that have an id that starts with Qty
be 5 characters wide. (Now size=5 isn't needed in the HTML 3 times) */
input[id^=Qty] { width:5em; }
/* The first <td> in each row should be 80px wide. Now we don't have to
clutter up the HTML with this and we don't have to repeat it 3 times. */
td:first-child { width:80px; }
</style>
</head> <!-- You didn't close your <head> tag! -->
<body>
<form>
<table border="1">
<tr>
<th>Item</th>
<th>Image</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
</tr>
<tr>
<td>Hat</td>
<td><img src="images/hat.jpg" alt="Hat"></td>
<td><input type="text" id="QtyA"></td>
<td>€3.00</td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<td id="TotalA"></td>
</tr>
<tr>
<td>T Shirt</td>
<td><img src="images/t_shirt.jpg" alt="T-Shirt"></td>
<td><input type="text" id="QtyB"></td>
<td>€4.00</td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<td id="TotalB"></td>
</tr>
<tr>
<td>Glasses</td>
<td><img src="images/glasses.jpg" alt="Glasses"></td>
<td><input type="text" id="QtyC"></td>
<td>€5.50</td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<td id="TotalC"></td>
</tr>
<tr>
<td> Total: </td>
<!-- You shouldn't be putting results of calculations into input fields
when you don't want the user to modify the data. Just place it into
an elmeent as its .textContent -->
<!-- You need to have this cell span over the remaining columns of the
table, so colspan=4 needs to be added. -->
<td id="grandTotal" colspan="4"></td>
</tr>
</table>
<!-- Your form doesn't actually submit data anywhere, so you shouldn't
have a submit button. A regular button will do. -->
<input type="button" value="Get Grand Total">
<input type="reset" value="Reset">
</form>
<script>
// Get references to the HTML elements that you'll be working with
var qtyBoxA = document.getElementById('QtyA');
var qtyBoxB = document.getElementById('QtyB');
var qtyBoxC = document.getElementById('QtyC');
var totBoxA = document.getElementById('TotalA');
var totBoxB = document.getElementById('TotalB');
var totBoxC = document.getElementById('TotalC');
var grandTot = document.getElementById('grandTotal');
var btnGetTot = document.querySelector("input[type=button]");
var btnReset = document.querySelector("input[type=reset]");
// Set up event handling in JavaScript, not HTML.
qtyBoxA.addEventListener("change", calc);
qtyBoxB.addEventListener("change", calc);
qtyBoxC.addEventListener("change", calc);
btnGetTot.addEventListener("click", getGrandTotal);
btnReset.addEventListener("click", reset);
var gt = null; // Will hold the grand total
function calc() {
var priceA = 3;
var priceB = 4;
var priceC = 5.50;
gt = 0;
// Convert the values in the quantity textboxes to numbers. The 10 that
// is being passed as the second argument indicates the "radix" or the
// numeric base system that should be used when the string is being
// interpreted. Here (and often), we work in the base 10 numeral system.
var qtyA = parseInt(qtyBoxA.value, 10);
var qtyB = parseInt(qtyBoxB.value, 10);
var qtyC = parseInt(qtyBoxC.value, 10);
// If each of the quantity fields are not empty, calculate the price * quantity
// for that row, place the answer in that row's total field and add the answer
// to the grand total
// NOTE: You had semicolons like this: if(); {}, which is incorrect.
// NOTE: Notice that there are + signs right in front of the total box references?
// this forces a conversion of the string in the text to a number. Since we
// just put a number into the cell, we know for sure it can be converted.
// NOTE: If parseInt() can't parse a number from the string provided, it returns NaN
// (Not A Number), we can check to see if we got NaN with the isNaN() function
// and here, we want to know if we don't have a NaN, so we prepend a ! to it
// (the logical NOT operator) to test the opposite of the isNaN() function result.
if (!isNaN(qtyA)) { totBoxA.textContent = qtyA * priceA; gt += +totBoxA.textContent; }
if (!isNaN(qtyB)) { totBoxB.textContent = qtyB * priceB; gt += +totBoxB.textContent; }
if (!isNaN(qtyC)) { totBoxC.textContent = qtyC * priceC; gt += +totBoxC.textContent; }
grandTot.textContent = gt.toFixed(2); // Just place the answer in an element as its text
}
function getGrandTotal(){
calc(); // Make sure all values are up to date
alert(gt);
}
function reset(){
// The built-in functionality of the <input type=reset> will clear out
// the quantity input fields automatically, but we need to manually reset
// non form field element that have been modified:
totBoxA.textContent = "";
totBoxB.textContent = "";
totBoxC.textContent = "";
grandTot.textContent = "";
}
</script>
</body>
</html>