Javascript计算器,如何保存等于后的显示值

时间:2019-02-08 00:45:50

标签: javascript

只要在每两个操作数计算后将其重置,此计算器就可以正常工作。我需要做的就是,如果我击中等于,则将当前的显示值用作下一次计算中的第一个操作数。我为自己的小解决方案感到骄傲,直到测试为止。这是我的代码

var backspaceBtn = document.getElementById("backspace");
var equalsBtn = document.getElementById("equals");
var decimalBtn = document.getElementById("decimal");
var clearBtn = document.getElementById("clear");
var operatorBtns = document.querySelectorAll(".operatorBtn");
var displayValEl = document.getElementById('display');
var calcNumBtns = document.getElementsByClassName("numBtn");
//variables to store operands and operators
var displayVal = "0";
var finalVal = "";
var operator = "";
var num1;
var num2;
// update display when user clicks number
var updateDisplay = (clkObj) => {
  var btnText = clkObj.target.innerText;
  if (displayVal === "0")
    displayVal = "";

  displayVal += btnText;
  displayValEl.innerText = displayVal;
}
//add event listeners to each num button,setting the click functon to update screen
for (let i = 0; i < calcNumBtns.length; i++) {
  calcNumBtns[i].addEventListener("click", updateDisplay, false);
}
// capturing the first number and operator when the operator btns are clicked
var operator1 = (clkObj) => {
  var sign = clkObj.target.innerText;
  switch (sign) {
    case "+":
      operator = "+"
      num1 = parseFloat(displayVal)
      displayVal = "0";
      displayValEl.innerText = displayVal
      break;
    case "-":
      operator = "-"
      num1 = parseFloat(displayVal)
      displayVal = "0";
      displayValEl.innerText = displayVal
      break;
    case "÷":
      operator = "÷"
      num1 = parseFloat(displayVal)
      displayVal = "0";
      displayValEl.innerText = displayVal
      break;
    case "x":
      operator = "x"
      num1 = parseFloat(displayVal)
      displayVal = "0";
      displayValEl.innerText = displayVal
      break;
    default:
      break;
  };
}
//adding event listener to the operator btns, setting click to update num1 and operator variables
for (let i = 0; i < operatorBtns.length; i++) {
  operatorBtns[i].addEventListener("click", operator1, false);
}
//adding decimal functionality, checking to see if one is present already. 
decimalBtn.onclick = () => {
  if (!displayVal.includes("."))
    displayVal += "."
  displayValEl.innerText = displayVal;
}
//capturing the second value and performing the operation
equalsBtn.onclick = () => {
  num2 = parseFloat(displayVal);
  switch (operator) {
    case '+':
      finalVal = num1 + num2;
      displayValEl.innerText = finalVal;
      break;
    case '-':
      finalVal = num1 - num2;
      displayValEl.innerText = finalVal;
      break;
    case 'x':
      finalVal = num1 * num2;
      displayValEl.innerText = finalVal;
      break;
      //nesting switches to check for division by zero.
    case '÷':
      switch (true) {
        case num1 === 0 || num2 === 0:
          alert("Cant devide by Zero")
          break;
      }
      finalVal = num1 / num2;
      displayValEl.innerText = finalVal;
      break;
    default:
      break;
  }
  num1 = displayVal;
  num2 = 0;
  operator = "";
}

clearBtn.onclick = () => {
  displayVal = "0";
  operator = "";
  num1 = 0
  num2 = 0
  displayValEl.innerText = displayVal;
}

backspaceBtn.onclick = () => {
  let lengthOfDisplay = displayVal.length;
  displayVal = displayVal.slice(0, lengthOfDisplay - 1)

  if (displayVal === "")
    displayVal = "0";

  displayValEl.innerText = displayVal;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" type="text/css" href="style.css">
  <title>Document</title>
</head>

<body>
  <header id="h-div">
    <p class="header-text">JavaScript Calculator</p>
  </header>
  <div class="background-wrapper">
    <div id="wrapper" class="main-grid">
      <div id="display">0</div>
      <div id="calc-body" class="calc-grid">
        <div id="add" class="calc-button operatorBtn btnText">+</div>
        <div id="subtract" class="calc-button operatorBtn btnText">-
        </div>
        <div id="multiply" class="calc-button operatorBtn 
btnText">x</div>
        <div id="divide" class="calc-button operatorBtn btnText">÷</div>

        <div id="num7" class="calc-button numBtn btnText">7</div>
        <div id="num8" class="calc-button numBtn btnText">8</div>
        <div id="num9" class="calc-button numBtn btnText">9</div>
        <div id="backspace" class="calc-button btnText 
backspaceBtn">&#8676;</div>

        <div id="num4" class="calc-button numBtn btnText">4</div>
        <div id="num5" class="calc-button numBtn btnText">5</div>
        <div id="num6" class="calc-button numBtn btnText">6</div>
        <div id="clear" class="calc-button btnText clearBtn">C</p>
        </div>

        <div id="num1" class="calc-button numBtn btnText">1</div>
        <div id="num2" class="calc-button numBtn btnText">2</div>
        <div id="num3" class="calc-button numBtn btnText">3</div>
        <div id="decimal" class="calc-button btnText decimalBtn">.</div>

        <div id="num0" class="calc-button numBtn btnText">0</div>
        <div id="equals" class="calc-button btnText operator-Btn 
 equalsBtn">=</div>
      </div>
    </div>
  </div>
  <script src="calcApp.js"></script>
</body>

</html>

我已经试过了,但是似乎没有完全重写就无法得到我需要做的事情。如果输入数字,请按一个运算符并添加另一个数字,然后按等于,您将得到正确的答案。甚至小数。但是,如果您将答案留在屏幕上,然后尝试按一个运算符和另一个操作数,则再次等于,这是非常严重的错误。我已经在HTML中添加了

2 个答案:

答案 0 :(得分:1)

这是解决问题的另一种方法-我将按下的按钮的文本添加到字符串中,并在需要时评估该字符串:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <div id="numbers">
        <div class="number">0</div>
        <div class="number">1</div>
        <div class="number">2</div>
        <div class="number">3</div>
        <div class="number">4</div>
        <div class="number">5</div>
        <div class="number">6</div>
        <div class="number">7</div>
        <div class="number">8</div>
        <div class="number">9</div>
    </div>

    <div id="operations">
        <div class="operation">+</div>
        <div class="operation">-</div>
        <div class="operation">*</div>
        <div class="operation">/</div>
    </div>

    <div id="control">
        <div id="equal">=</div>
        <div id="reset">C</div>
    </div>

    <div id="result">Res</div>


</body>

</html>

<style>
    body {
        width: 100%;
        height: 100%;
        margin: 0;
        background-color: #96a5af;
    }


    #numbers>.number {
        display: inline;
    }

    #operations>.operation {
        display: inline;
    }

    #contro>* {}
</style>


<script>
    // getting all nodes
    const numbers = Array.from(document.getElementById("numbers").children);
    const operations = Array.from(document.getElementById("operations").children);

    const calc = document.getElementById("equal");
    const equal = document.getElementById("result");
    const reset = document.getElementById("reset");

    // calcualtion is the calculation we watnt to do
    let calculation = "";

    // [...numbers, ...operations] combines the numbers and operations array so I dont have to create an eventlister for both
    [...numbers, ...operations].forEach((el) => {
        document.addEventListener("click", (e) => {
            //My Code is not Ideal, so I check here wearhter I accually clicked on the button I wanted to
            if (e.target.isSameNode(el)) {
                // and add the text of the button to my calculation
                calculation += e.target.innerText;
                console.log('e.target.innerText', e.target.innerText)

                // if I just added a number, I show my current result
                if (!isNaN(parseFloat(+e.target.innerText)) && isFinite(e.target.innerText)) {
                    evaluate();
                }
            }

        })
    })

    // manually calculate result
    calc.addEventListener("click", () => {
        evaluate()
    })

    // reset by clearing calculation
    reset.addEventListener("click", () => {
        calculation = "";
    })

    // helper function which calculates result and sets my HTML to it
    const evaluate = () => {
        equal.innerHTML = eval(calculation) + "";
    };
</script>

codepen:https://codepen.io/anon/pen/qgpove

编辑: 一个不用eval进行计算的例子

const str = "3+45*5/5+3";

const evalute = () => {
    let strArr = str.split(/([+\-*/](?=[0-9]+))|(?=[+\-*/])/);
    let pos;

    do  {
        pos = strArr.findIndex(el => el == "*")
        if (!!~pos) strArr.splice(pos - 1, 3, +strArr[pos - 1] * +strArr[pos + 1]);
    } while (!!~pos);

    do  {
        pos = strArr.findIndex(el => el == "/")
        if (!!~pos) strArr.splice(pos - 1, 3, +strArr[pos - 1] / +strArr[pos + 1]);
    } while (!!~pos);

    do  {
        pos = strArr.findIndex(el => el == "+")
        if (!!~pos) strArr.splice(pos - 1, 3, +strArr[pos - 1] + +strArr[pos + 1]);
    } while (!!~pos);

    do  {
        pos = strArr.findIndex(el => el == "-")
        if (!!~pos) strArr.splice(pos - 1, 3, +strArr[pos - 1] - +strArr[pos + 1]);
    } while (!!~pos);

    return strArr[0];
}

console.log(evalute(str));

答案 1 :(得分:0)

您要保留更改并在后续计算中使用保留的值。因此,您实际上将重构您的equalsBtn点击处理程序来做到这一点。

equalsBtn.onclick = () => {  
  num2 = parseFloat(displayVal);

  switch (operator) {
    case '+':
      finalVal += num2;          
      break;
    case '-':
      finalVal -= num2;
      break;
    case 'x':
      finalVal *= num2;  
      break;
    case '÷':
      //for division by zero.
      if (num2 === 0)
      {
        alert("Cant divide by Zero");
        return;
      }
      finalVal /= num2;
      break;
    default:
      break;
  }
  displayValEl.innerText = finalVal.toString();
  num1 = num2;
  num2 = 0;
  operator = "";
};

您还需要确保在finalVal点击处理程序中清除了clearBtn

clearBtn.onclick = () => {
  displayVal = "0";
  operator = "";
  num1 = 0;
  num2 = 0;
  finalVal = 0;
  displayValEl.innerText = displayVal;
};

编辑:此外,对于此值持久性的状态,您应该处理一些方案:在初始化,updateDisplay,操作员单击和deleteBtn单击的范围内,以解决其他期望。

var backspaceBtn = document.getElementById("backspace");
var equalsBtn = document.getElementById("equals");
var decimalBtn = document.getElementById("decimal");
var clearBtn = document.getElementById("clear");
var operatorBtns = document.querySelectorAll(".operatorBtn");
var displayValEl = document.getElementById('display');
var calcNumBtns = document.getElementsByClassName("numBtn");
//variables to store operands and operators
var displayVal = "0";
var operator = "";
var finalVal = 0;
var num1 = 0;
var num2 = 0;

// update display when user clicks number
var updateDisplay = (clkObj) => {
  var btnText = clkObj.target.innerText;

  var shouldResetCalc = (operator === "" && finalVal !== 0);
  
  displayVal = (displayVal === "0" || shouldResetCalc)
    ? btnText 
    : displayVal + btnText;

  if (shouldResetCalc)
    finalVal = 0;
    
  displayValEl.innerText = displayVal;
}

//add event listeners to each num button,setting the click functon to update screen
for (let i = 0, max = calcNumBtns.length; i < max; i++) {
  calcNumBtns[i].addEventListener("click", updateDisplay, false);
}

// capturing the first number and operator when the operator btns are clicked
var operator1 = (clkObj) => {
  var sign = clkObj.target.innerText;

  switch (sign) {
    case "+":
      operator = "+"
      num1 = parseFloat(displayVal);
      clearDisplay();
      break;
    case "-":
      operator = "-"
      num1 = parseFloat(displayVal);
      clearDisplay();      
      break;
    case "÷":
      operator = "÷"
      num1 = parseFloat(displayVal);
      clearDisplay();
      break;
    case "x":
      operator = "x"
      num1 = parseFloat(displayVal)
      clearDisplay();
      break;
    default:
      break;
  }
  if (finalVal === 0 && num1 !== 0)
      finalVal = num1;
};

//adding event listener to the operator btns, setting click to update num1 and operator variables
for (let i = 0; i < operatorBtns.length; i++) {
  operatorBtns[i].addEventListener("click", operator1, false);
}

//adding decimal functionality, checking to see if one is present already. 
decimalBtn.onclick = () => {
  if (!displayVal.includes("."))
    displayVal += "."

  displayValEl.innerText = displayVal;
}

//capturing the second value and performing the operation
equalsBtn.onclick = () => {  
  num2 = parseFloat(displayVal);
  
  switch (operator) {
    case '+':
      finalVal += num2;          
      break;
    case '-':
      finalVal -= num2;
      break;
    case 'x':
      finalVal *= num2;  
      break;
    case '÷':
      //for division by zero.
      if (num2 === 0)
      {
        alert("Cant divide by Zero");
        return;
      }
      finalVal /= num2;
      break;
    default:
      break;
  }
  displayVal = finalVal.toString()
  displayValEl.innerText = displayVal;
  num1 = num2;
  operator = "";
};

function clearValues() {
  num1 = 0;
  num2 = 0;
  finalVal = 0;
}

function clearDisplay() {
  displayVal = "0";
  displayValEl.innerText = displayVal;
}

clearBtn.onclick = () => {
  operator = "";
  clearValues();
  clearDisplay();
};

backspaceBtn.onclick = () => {
  let lengthOfDisplay = displayVal.length;
  displayVal = displayVal.slice(0, lengthOfDisplay - 1)

  var shouldResetCalc = (operator === "" && finalVal !== 0);
  
  if (displayVal === "")
    displayVal = "0";

  if (shouldResetCalc)
    finalVal = 0;
    
  displayValEl.innerText = displayVal;
};
button { min-width: 40px;}

.container > .container {margin-top: 1em;}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<div class="container">
  <div class="xs-col-6 container">
    <div class="row xs-col-12">
      <button class="numBtn xs-col-4">7</button>
      <button class="numBtn xs-col-4">8</button>
      <button class="numBtn xs-col-4">9</button>
    </div>
    <div class="row xs-col-12">
      <button class="numBtn xs-col-4">4</button>
      <button class="numBtn xs-col-4">5</button>
      <button class="numBtn xs-col-4">6</button>
    </div>
    <div class="row xs-col-12">
      <button class="numBtn xs-col-4">1</button>
      <button class="numBtn xs-col-4">2</button>
      <button class="numBtn xs-col-4">3</button>
    </div>
    <div class="row xs-col-12">
      <button class="numBtn xs-col-4">0</button>
      <button id="decimal" class="xs-col-4">.</button>
      <button id="equals" class="xs-col-4">=</button>
    </div>
  </div>
  <div class="xs-col-6 container">
    <div class="row xs-col-12">
      <button class="operatorBtn divide">÷</button>
      <button class="operatorBtn muliply">x</button>
      <button class="operatorBtn subtract">-</button>
      <button class="operatorBtn add">+</button>
    </div>
    <div class="row xs-col-12">
      <button id="backspace">Del</button>
      <button id="clear">Clr</button>
    </div>
  </div>
</div>

<div id="display">
</div>