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

时间:2017-10-31 05:24:26

标签: javascript html css

我在Javascript中为FreeCodeCamp构建计算器。我对代码的一部分有问题。当我添加诸如" - "," +"," x"等操作符时,历史记录部分中的数字会重复。例如,如果我输入" 5"," 5"出现在历史区域。然后我进入了#34; +"历史显示" 5 + 5 +"。

此外,我希望计算器与Mac计算机中的计算器类似。换句话说,如果我输入" 5",然后输入" +",我想要" 5" " 5 +"留在显示区域显示在历史记录区域中,直到按下下一个数字。然后它将显示下一个数字,而历史显示" 5 + 6"。我如何解决这两个问题?

这是我的codepen链接:https://codepen.io/kikibres/pen/MEQvqv

你也可以在这里看到它:



$(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>
&#13;
&#13;
&#13;

我遇到问题的部分是:

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

********* UPDATE **************** ****************** 到目前为止,我能够解决历史区域问题。但是,我无法解决显示问题。现在的问题是每次我点击&#34; 7&#34;等数字,然后点击&#34; +&#34;等操作符,显示区域中的数字变回&# 34; 0&#34 ;.此外,在操作员之后,我然后点击另一个数字,例如&#34; 3&#34;,它显示为&#34; 03&#34;在显示区域......这是我的更新代码:

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

1 个答案:

答案 0 :(得分:0)

对于第二个问题,您必须将显示逻辑和计算逻辑分开。你想要的是:

  • 键入数字=&gt;显示数字或结果(单独的功能,单独的变量)
  • number or operator =&gt;计算(另一个函数,其他变量)

在您的代码中,两种逻辑是混合的。

尽可能地帮助您。您可以使用调试器并逐步使用它或在代码中添加utilies函数,如下所示:

&#13;
&#13;
$(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;
  };
  
  
  });
&#13;
@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;}
&#13;
<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>
&#13;
&#13;
&#13;

这样做,您可以立即看到问题发生的位置。这是:subMath = at bottom of addOperator 8+8+

然后很容易解决。

也许另一种方法也可以帮到你。请参阅下面的一个(不完全相同的行为,但您可以轻松地更改它):

&#13;
&#13;
$(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', i.e. 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());
    }
    
  
  });
&#13;
@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;}
&#13;
<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>
&#13;
&#13;
&#13;