簡體   English   中英

在javascript中的訂單上計算數量和總計

[英]Calculate quantity and total on an order form in javascript

我正在尋找一些代碼幫助。 我應該創建一個表格,允許用戶輸入他們想購買的商品的數量。 輸入數量后,將顯示該特定項目的總價,以及所有采購的總計(在表格底部)。 當用戶按下提交按鈕時,將彈出一個警報彈出窗口。

我在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()將運行它。 在您的代碼中,您對在文本框中輸入的value運行eval() ,並且由於您不知道將輸入什么值,因此您也不知道eval()將接收什么字符串。 這相當於一個巨大的安全漏洞,這是不應使用eval()的原因之一。 其次,即使在完美的環境中, eval()也很慢,因此從純粹的性能角度來看,您不希望使用它。 坦白說,我震驚於有人教您使用它,尤其是將字符串轉換為數字的過程。 僅此一項就足以索回您的錢!

在您的情況下,您需要將字符串輸入轉換為數字,以便可以對輸入進行數學運算。 JavaScript提供了幾種方法來做到這一點:

不要在帶有事件屬性的HTML中設置事件處理。 首次創建JavaScript(25年前)時,為HTML元素(又稱為DOM元素)設置事件處理程序的方法是使用HTML屬性(例如onclickonchangeonmouseover等)與元素內聯。 HTML。 不幸的是,由於該技術看起來如此簡單,因此它被一遍又一遍地使用,而不是死於它應得的迅速死亡。 幾種原因不使用這種過時的技術 如今,我們已經遵循了現代標准和最佳實踐,因此,事件處理應使用.addEventListener()與HTML分開的JavaScript進行。

另外,您的onchange "calc()"代碼還是不正確的,因為該代碼應該是: onchange = "calc()"

另外,考慮哪些元素需要為其設置事件。 您的原始代碼進行了設置,因此,如果總數更改了, calc()將運行,但這沒有任何意義。 為什么有人可以直接更改總數,而這樣做實際上會導致發生什么呢? 數量會因為總數發生變化而改變嗎?

注意細節您有3行來計算3數量* 3價格以得到3總數,但是您只是復制/粘貼了3行的HTML,並用3個具有相同QtyA id的輸入元素來QtyA即使您的JavaScript是正確尋找QtyBQtyC

使用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> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM