简体   繁体   中英

Why calculator works incorrectly?

I am trying to make my first calculator with vanilla JS. My logic is the following.

  • You click on a number(1/2)
  • you hit on a sign (plus/minus)
  • you click on a second number
  • you hit equals and get an answer.

My equals button gets different functions through plus and minus. However, it does not work properly. 1 - 2 = -1 but then when you do +2 it gets -3 instead of 1 .

What is wrong?

 var screen = document.getElementById('hres'); var numI = 0; var numII = 0; document.getElementById('one').addEventListener("click", uno); function uno() { screen.value = 1; } document.getElementById('two').addEventListener("click", duo); function duo() { screen.value = 2; } function plus() { numI = screen.value; document.getElementById('eql').addEventListener('click', equalP); } function equalP() { numII = screen.value; screen.value = +numI + +numII; } function minus() { numI = screen.value; document.getElementById('eql').addEventListener('click', equalM); } function equalM() { numII = screen.value; screen.value = numI - numII; } 
 #hres { position: relative; text-align: center; line-height: 50px; font-size: 22pt; width: 200px; height: 50px; margin-bottom: 65px; } #sum { display: inline-block; font-size: 20pt; border: 2px solid black; margin: 5px; text-align: center; line-height: 50px; width: 200px; height: 50px; background-color: goldenrod; } #one { display: inline-block; font-size: 20pt; width: 50px; height: 50px; background-color: hotpink; text-align: center; line-height: 50px; border: 2px solid black; } #two { display: inline-block; font-size: 20pt; width: 50px; height: 50px; background-color: hotpink; text-align: center; line-height: 50px; border: 2px solid black; } #eql { display: inline-block; font-size: 20pt; border: 2px solid black; margin: 5px; text-align: center; line-height: 50px; width: 200px; height: 50px; background-color: skyblue; transition: .3s; } #sub { display: inline-block; font-size: 20pt; border: 2px solid black; margin: 5px; text-align: center; line-height: 50px; width: 200px; height: 50px; background-color: lightgray; } 
 <input id="hres" readonly></input><br> <div id="one">1</div> <div id="two">2</div><br> <button onclick="plus()" id="sum">+</button> <button onclick="minus()" id="sub">-</button> <button id="eql">=</button> 

First of all lets identify the problems:

  1. You are registering the event listener for the equals button every time you click plus or minus. This means the event function will run as many times as it is registered and will effect your results
  2. You are not re-adjusting your variables. After equals you want numI to become the new total, so that you can store the next operation value in num2 and then perform the correct calculation on equals

To achieve this requires a fair bit of refactoring of your code. I have highlighted the important bits with comments:

// Register all events once, and once only.
document.getElementById('sum').addEventListener("click", plus);
document.getElementById('sub').addEventListener("click", minus);
document.getElementById('eql').addEventListener('click', equal);
document.getElementById('one').addEventListener("click", uno);
document.getElementById('two').addEventListener("click", duo);

// Get input element for display purposes.
var screen = document.getElementById('hres');

// Variables to hold the numbers we are working with, and the operation symbol.
var numI = 0;
var numII = 0;
var operation = null;

// Simple functions to handle each number button.
// You could use a data-* attribute and have a sinle generic function.
function uno() {
  setNumber(1);
}

function duo() {
  setNumber(2);
}

// Function that processes any number provided.
// The key here is to check if the user has click an operations button,
// if so then we want to set the second variable. Otherwise set the first.
function setNumber(n) {
  screen.value = n;
  if (operation)
    numII = n;
  else
    numI = n;
}

// Basic functions to set the operation type. Again, data-* attribute would be useful.
function plus() {
  operation = '+';
}

function minus() {
  operation = '-';
}

// Function to calculate result.
// Here we check what the operation is and apply the correct logic to match.
// Importantly, at the end, we assign the result to numI so it is ready for the next operation.
function equal() {
  var result = 'err';
  if (operation == '+')
    result = numI + numII;
  else if (operation == '-')
    result = numI - numII;
  numI = result;
  screen.value = result;
}

Here is a working example.


NOTE: Even with these changes their isn't any validation on user input. It very much relies on the user pressing buttons in the correct order (ie number > operation > number > equals > operation/number, etc.). You should consider this if you want to further improve your code, it would be out of scope for me to provide that as an answer to this question though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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