简体   繁体   English

计算器Javascript中的运算符无法正常运行

[英]The Operators in Calculator Javascript isn't working properly

I'm building a calculator for FreeCodeCamp in Javascript. 我正在用Javascript为FreeCodeCamp构建一个计算器。 I'm having problem with one part of the code. 我对一部分代码有疑问。 When I add an operator such as "-", "+", "x", and so on, the numbers in the history section repeat itself. 当我添加诸如“-”,“ +”,“ x”之类的运算符时,历史记录部分中的数字会重复其自身。 For example, if I entered "5", "5" appears in the history area. 例如,如果我输入“ 5”,则“ 5”出现在历史记录区域中。 Then I entered "+" and the history shows "5+5+". 然后我输入“ +”,历史记录显示为“ 5 + 5 +”。

Additionally, I wanted the calculator to work similar to the calculator found in Mac computers. 另外,我希望计算器的工作方式类似于Mac计算机中的计算器。 In other words, if I entered "5", then entered "+", I wanted the "5" to stay in the display area while "5+" shows up in the history area until next number is pressed. 换句话说,如果我输入“ 5”,然后输入“ +”,我希望“ 5”留在显示区域,而“ 5+”出现在历史记录区域中,直到按下下一个数字。 Then it will display next number while the history shows "5+6". 当历史记录显示为“ 5 + 6”时,它将显示下一个数字。 How do I solve both problems? 我该如何解决这两个问题?

Here is my codepen link: https://codepen.io/kikibres/pen/MEQvqv 这是我的代码笔链接: https ://codepen.io/kikibres/pen/MEQvqv

You can see it also here: 您也可以在这里看到它:

 $(document).ready(function() { var mainMath = "0"; var subMath = "0"; update(); var period = /\\./; $("button").click(function(){ calculate($(this).attr("value")); }); function calculate(keyitem) { switch(keyitem) { case "clear": clearScreen(); break; case "plusminus": plusminusScreen(); break; case "%": percentageScreen(); break; case "/": case "*": case "+": case "-": addOperator(keyitem); break; case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case ".": addNumber(keyitem); break; case "=": solveEqual(); break; } update(); }; function clearScreen() { mainMath = "0"; subMath = "0"; }; function plusminusScreen() { mainMath = -1 * mainMath; subMath = -1 * subMath; }; function addNumber(keyitem) { if (keyitem == "."){ if(mainMath == 0 && subMath == 0) { mainMath = "0" + keyitem; subMath = "0" + keyitem; return; } } if (mainMath == "0" && subMath == "0"){ mainMath=keyitem; subMath=keyitem; return; } mainMath+=keyitem; subMath+=keyitem; }; function addOperator(keyitem){ addNumber(keyitem); subMath += mainMath; mainMath = keyitem; }; function update(){ document.getElementById("answer").innerHTML = mainMath; document.getElementById("history").innerHTML = subMath; }; }); 
 @import url('https://fonts.googleapis.com/css?family=Roboto:300,400'); h1, h2, h3, p { font-family: 'Roboto', sans-serif; } html, body{ height:100%; margin: 0; background-color: #ffffff; } .wrapper { width: 100%; height: 100%; position: relative; display:flex; flex-direction:column; justify-content:center; align-items:center; background-repeat: no-repeat; background-size: cover; background-position: center center; padding: 160px 0; } .calculatorbox { width: 260px; margin: 0 auto; border: 1px solid #000000; } .calheader { text-align: center; } .calwindow { background: #000000; position: relative; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-flex-direction: column; /* Safari */ flex-direction: column; -webkit-justify-content: flex-end; justify-content: flex-end; -webkit-align-items: flex-end; align-items: flex-end; padding: 10px 0; box-sizing: border-box; } .entry { font-size: 4em; display: block; line-height: 1em; } .entryhistory { font-size: 1em; padding-right: 5px; } .entry p, .entryhistory p { margin: 0; color: #ffffff; } sup { top: -0.5em; } sub { bottom: -0em; } .row { clear: both; width: 100%; display: flex; } button { display: inline-block; border: none; padding: 0; outline: none; cursor: pointer; } .key { width: 65px; height: 60px; font-size: 22px; border-top: 1px solid rgba(0, 0, 0, 0.3); border-right: 1px solid rgba(0, 0, 0, 0.3); box-sizing: border-box; } .key.btnspan { width: 130px; } .key.topcolor { background: #d9d9d9; } .key.orange { background: #ff8c00; color: #ffffff; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="wrapper"> <div class="calheader"> <h2>Simple Calculator</h2> </div> <div class="calculatorbox"> <div class="calwindow"> <!-- ENTRY BOX --> <div class="entry"> <p id="answer"></p> </div> <div class="entryhistory"> <p id="history"></p> </div> </div> <!-- BUTTONS --> <div class="calbuttons"> <div class="row"> <button class="key topcolor" value="clear">C</button> <button class="key topcolor" value="plusminus"><sup>+</sup>/<sub>−</sub></button> <button class="key topcolor" value="%">%</button> <button class="key orange" value="/">÷</button> </div> <div class="row"> <button class="key" value="7">7</button> <button class="key" value="8">8</button> <button class="key" value="9">9</button> <button class="key orange" value="*">×</button> </div> <div class="row"> <button class="key" value="4">4</button> <button class="key" value="5">5</button> <button class="key" value="6">6</button> <button class="key orange" value="-">−</button> </div> <div class="row"> <button class="key" value="1">1</button> <button class="key" value="2">2</button> <button class="key" value="3">3</button> <button class="key orange" value="+">+</button> </div> <div class="row"> <button class="key btnspan" value="0">0</button> <button class="key" value=".">.</button> <button class="key orange" value="=">=</button> </div> </div> </div> </div> 

The part that I'm having problem with is this: 我遇到问题的部分是:

function addOperator(keyitem){
    addNumber(keyitem);
    subMath += mainMath;
    mainMath = keyitem;
  };

******************************UPDATE********************************** So far I was able to resolve the history area problem. ******************************更新******************* ***************到目前为止,我已经能够解决历史记录区域的问题。 However, I am unable to solve the display problem. 但是,我无法解决显示问题。 The problem now is every time I click on a number such as "7", then click on an operator such as "+", the number in the display area changed back to "0". 现在的问题是,每次我单击“ 7”之类的数字,然后单击“ +”之类的运算符时,显示区域中的数字都会变回“ 0”。 Additionally, after the operator, I then click on another number such as "3", it shows up as "03" in the display area... Here's my updated code: 另外,在操作员之后,我然后单击另一个数字,例如“ 3”,它在显示区域中显示为“ 03”。这是我更新的代码:

function addOperator(keyitem){
    if(mainMath == "0"){
      /*subMath === "0";*/
      return;
    }
    /*addNumber(keyitem);*/
    subMath += keyitem;
    mainMath = "0";
  };

For the second problem, you have to separate the displaying logic and the calculation logic. 对于第二个问题,您必须将显示逻辑和计算逻辑分开。 What you want is: 您想要的是:

  • when you type a number => display the number OR the result (separate function, separate variables) 当您键入数字=>显示数字或结果时(单独的函数,单独的变量)
  • number or operator => calculate (another function, other variables) 数字或运算符=>计算(另一个函数,其他变量)

In your code, the two logics are mixed. 在您的代码中,这两种逻辑混合在一起。

Try to help you as best as you can. 尽力为您提供最大的帮助。 You can use a debugger and use it step by step or add utilies function in your code like this: 您可以使用调试器并逐步使用它,也可以在代码中添加utilies函数,如下所示:

 $(document).ready(function() { // My check point function function ckval(name, where){ if (undefined != where) { where += ' ' } console.log(name + " " + where + "= ", eval(name)) } var mainMath = "0"; var subMath = "0"; update(); var period = /\\./; $("button").click(function(){ calculate($(this).attr("value")); }); function calculate(keyitem) { switch(keyitem) { case "clear": clearScreen(); break; case "plusminus": plusminusScreen(); break; case "%": percentageScreen(); break; case "/": case "*": case "+": case "-": addOperator(keyitem); break; case "0": case "1": case "2": case "3": case "4": case "5": case "6": case "7": case "8": case "9": case ".": addNumber(keyitem); break; case "=": solveEqual(); break; } update(); }; function clearScreen() { mainMath = "0"; subMath = "0"; }; function plusminusScreen() { mainMath = -1 * mainMath; subMath = -1 * subMath; }; function addNumber(keyitem) { console.log("-> addNumber("+keyitem+")",); // <- method if (keyitem == "."){ if(mainMath == 0 && subMath == 0) { mainMath = "0" + keyitem; subMath = "0" + keyitem; return; } } if (mainMath == "0" && subMath == "0"){ mainMath=keyitem; subMath=keyitem; return; } mainMath+=keyitem; subMath+=keyitem; ckval('mainMath', 'at bottom of addNumber'); // <- checkPoint ckval('subMath', 'at bottom of addNumber'); // <- checkPoint }; function addOperator(keyitem){ console.log("-> addOperation("+keyitem+")"); ckval('mainMath'); // <- checkPoint ckval('subMath'); // <- checkPoint addNumber(keyitem); ckval('mainMath', 'after addNumber'); // <- checkPoint ckval('subMath', 'after addNumber'); // <- checkPoint subMath += mainMath; mainMath = keyitem; ckval('mainMath', 'at bottom of addOperator'); // <- checkPoint ckval('subMath', 'at bottom of addOperator'); // <- checkPoint }; function update(){ document.getElementById("answer").innerHTML = mainMath; document.getElementById("history").innerHTML = subMath; }; }); 
 @import url('https://fonts.googleapis.com/css?family=Roboto:300,400');h1, h2, h3, p { font-family: 'Roboto', sans-serif;}html, body{ height:100%; margin: 0; background-color: #ffffff;}.wrapper { width: 100%; height: 100%; position: relative; display:flex; flex-direction:column; justify-content:center; align-items:center; background-repeat: no-repeat; background-size: cover; background-position: center center; padding: 160px 0;}.calculatorbox { width: 260px; margin: 0 auto; border: 1px solid #000000;}.calheader { text-align: center;}.calwindow { background: #000000; position: relative; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-flex-direction: column; /* Safari */ flex-direction: column; -webkit-justify-content: flex-end; justify-content: flex-end; -webkit-align-items: flex-end; align-items: flex-end; padding: 10px 0; box-sizing: border-box;}.entry { font-size: 4em; display: block; line-height: 1em;}.entryhistory { font-size: 1em; padding-right: 5px;}.entry p, .entryhistory p { margin: 0; color: #ffffff;}sup { top: -0.5em;}sub { bottom: -0em;}.row { clear: both; width: 100%; display: flex;}button { display: inline-block; border: none; padding: 0; outline: none; cursor: pointer;}.key { width: 65px; height: 60px; font-size: 22px; border-top: 1px solid rgba(0, 0, 0, 0.3); border-right: 1px solid rgba(0, 0, 0, 0.3); box-sizing: border-box;}.key.btnspan { width: 130px;}.key.topcolor { background: #d9d9d9;}.key.orange { background: #ff8c00; color: #ffffff;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="wrapper"><div class="calheader"><h2>Simple Calculator</h2></div><div class="calculatorbox"><div class="calwindow"> <!-- ENTRY BOX --> <div class="entry"> <p id="answer"></p> </div> <div class="entryhistory"> <p id="history"></p> </div></div><!-- BUTTONS --><div class="calbuttons"> <div class="row"> <button class="key topcolor" value="clear">C</button> <button class="key topcolor" value="plusminus"><sup>+</sup>/<sub>−</sub></button> <button class="key topcolor" value="%">%</button> <button class="key orange" value="/">÷</button> </div> <div class="row"> <button class="key" value="7">7</button> <button class="key" value="8">8</button> <button class="key" value="9">9</button> <button class="key orange" value="*">×</button> </div> <div class="row"> <button class="key" value="4">4</button> <button class="key" value="5">5</button> <button class="key" value="6">6</button> <button class="key orange" value="-">−</button> </div> <div class="row"> <button class="key" value="1">1</button> <button class="key" value="2">2</button> <button class="key" value="3">3</button> <button class="key orange" value="+">+</button> </div> <div class="row"> <button class="key btnspan" value="0">0</button> <button class="key" value=".">.</button> <button class="key orange" value="=">=</button> </div></div></div></div> 

Doing that, you see immediatly where the problem happen. 这样,您可以立即看到问题发生的位置。 Here's: subMath = at bottom of addOperator 8+8+ . 这是: subMath = at bottom of addOperator 8+8+

Then easy to fix. 然后容易修复。


Maybe another approach could help you too. 也许另一种方法也可以帮助您。 See the one below (not exactly the same behaviour, but you could change it easily): 请参阅以下内容(行为不完全相同,但是您可以轻松更改):

 $(document).ready(function() { // +stackOperations+ keeps every user action let stackOperations = [] // +currentDispQueue+ keeps trace of the current top display , currentDispQueue = '' ; // To catch the user click event $("button").click(function(){ catchClick($(this).attr("value")); }); /** * Catch the user click * Note: 'calculate' is a less good name for this fonction * // function calculate(keyitem) { */ function catchClick(keyitem) { switch(keyitem) { case "clear": return reset() ; // clearScreen is actually a `reset` case "plusminus": if (stackOperations.length) { currentDispQueue = '' ; updateUserDisplay('-' + currentDispQueue) ; stackOperations.push({type: 'operator', value: '*-1'}) }; break; case "/":case "*": case "+": case "-": case '.': currentDispQueue = '' ; stackOperations.push({type: 'operator', value: keyitem}); break; case "=": return displayTotal(); default: if (keyitem >= 0 && keyitem < 10) { stackOperations.push({type: 'number', value: parseInt(keyitem)}) displayCurrentQueue( currentDispQueue + keyitem ); // "6"+"3" => "63" } }; displayCurrentHistory(); // always (each user action => reaction) } /** * Display the result of the calc */ function displayTotal() { displayCurrentQueue(calculProceed()); } /** * Reset App */ function reset() { stackOperations = [] ; currentDispQueue = '' ; displayCurrentHistory('&nbsp;') ; displayCurrentQueue() ; }; reset(); /** * Display methods */ function displayCurrentQueue(displayedValue){ document.getElementById("answer").innerHTML = displayedValue || '0'; if (displayedValue) currentDispQueue = displayedValue ; } function displayCurrentHistory(){ document.getElementById("history").innerHTML = history(); } /** * Calc methods * */ /** Return the 'history', ie the calcul as a string */ function history() { return stackOperations.reduce( (x, y) => { return x + y.value } , ''); } /** Eval the history and return it */ function calculProceed() { return eval(history()); } }); 
 @import url('https://fonts.googleapis.com/css?family=Roboto:300,400');h1, h2, h3, p { font-family: 'Roboto', sans-serif;}html, body{ height:100%; margin: 0; background-color: #ffffff;}.wrapper { width: 100%; height: 100%; position: relative; display:flex; flex-direction:column; justify-content:center; align-items:center; background-repeat: no-repeat; background-size: cover; background-position: center center; padding: 160px 0;}.calculatorbox { width: 260px; margin: 0 auto; border: 1px solid #000000;}.calheader { text-align: center;}.calwindow { background: #000000; position: relative; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-flex-direction: column; /* Safari */ flex-direction: column; -webkit-justify-content: flex-end; justify-content: flex-end; -webkit-align-items: flex-end; align-items: flex-end; padding: 10px 0; box-sizing: border-box;}.entry { font-size: 4em; display: block; line-height: 1em;}.entryhistory { font-size: 1em; padding-right: 5px;}.entry p, .entryhistory p { margin: 0; color: #ffffff;}sup { top: -0.5em;}sub { bottom: -0em;}.row { clear: both; width: 100%; display: flex;}button { display: inline-block; border: none; padding: 0; outline: none; cursor: pointer;}.key { width: 65px; height: 60px; font-size: 22px; border-top: 1px solid rgba(0, 0, 0, 0.3); border-right: 1px solid rgba(0, 0, 0, 0.3); box-sizing: border-box;}.key.btnspan { width: 130px;}.key.topcolor { background: #d9d9d9;}.key.orange { background: #ff8c00; color: #ffffff;} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="wrapper"><div class="calheader"><h2>Simple Calculator</h2></div><div class="calculatorbox"><div class="calwindow"> <!-- ENTRY BOX --> <div class="entry"> <p id="answer"></p> </div> <div class="entryhistory"> <p id="history"></p> </div></div><!-- BUTTONS --><div class="calbuttons"> <div class="row"> <button class="key topcolor" value="clear">C</button> <button class="key topcolor" value="plusminus"><sup>+</sup>/<sub>−</sub></button> <button class="key topcolor" value="%">%</button> <button class="key orange" value="/">÷</button> </div> <div class="row"> <button class="key" value="7">7</button> <button class="key" value="8">8</button> <button class="key" value="9">9</button> <button class="key orange" value="*">×</button> </div> <div class="row"> <button class="key" value="4">4</button> <button class="key" value="5">5</button> <button class="key" value="6">6</button> <button class="key orange" value="-">−</button> </div> <div class="row"> <button class="key" value="1">1</button> <button class="key" value="2">2</button> <button class="key" value="3">3</button> <button class="key orange" value="+">+</button> </div> <div class="row"> <button class="key btnspan" value="0">0</button> <button class="key" value=".">.</button><button class="key orange" value="=">=</button></div></div></div></div> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM