Неожиданный вывод с помощью простого проекта калькулятора

#javascript

#javascript

Вопрос:

Мой ожидаемый результат с помощью приведенной ниже программы для примера ввода (1 2 =):

  • console.log(currentNumber) = 1
  • console.log(currentOperator) =
  • console.log(nextNumber) = 2
  • console.log(operatorActive) = false

Тем не менее, я получаю:

  • console.log(currentNumber) = 2 ***
  • console.log(currentOperator) =
  • console.log(nextNumber) = не определено ***
  • console.log(operatorActive) = false

*** = неожиданный вывод


Я пытаюсь заставить калькулятор сказать 3, как только я введу эти значения. Очевидно, консоль.журналы показывают обратное. Кажется, я не могу понять, что не так с моим кодом. Помощь очень ценится.

 // Functions for calculation ( , -, *, /)

const add = (a, b) => a   b;
const subtract = (a, b) => a - b;
const multiply = (a, b) => a * b;
const divide = (a, b) => a / b;

const operate = (operator, a, b) => {
  switch (operator) {
    case " ":
      return add(a, b);
    case "-":
      return subtract(a, b);
    case "×":
      return multiply(a, b);
    case "÷":
      return divide(a, b);
  }
};

// DOM selection of UI buttons and display

const numbers = document.querySelectorAll(".number");
const operators = document.querySelectorAll(".operator");
const equals = document.querySelector(".equals");
const display = document.querySelector(".output");

// Functions for event listeners when buttons clicked...

let currentNumber;
let currentOperator;
let nextNumber;
let operatorActive = false;

// ... for numerical buttons

function clickNumber() {
  numbers.forEach((number) => {
    if (!operatorActive) {
      number.addEventListener('click', () => {
        display.textContent  = number.textContent;
        currentNumber = display.textContent;
      })
    } else if (operatorActive) {
      number.addEventListener('click', () => {
        display.textContent  = number.textContent;
        nextNumber = display.textContent;
      })
    }
  });
}

// ... for operator buttons

function clickOperator() {
  operators.forEach((operator) => {
    operator.addEventListener('click', () => {
      currentOperator = operator.textContent;
      display.textContent = "";
      operatorActive = true;
    })
  });
}

// ... for equals button

function clickEquals(x, y, z) {
  equals.addEventListener('click', () => {
    operatorActive = false;
    // **below console logs are tests to see what values hold
    console.log(currentNumber);
    console.log(currentOperator);
    console.log(nextNumber);
    console.log(operatorActive);
    
    display.textContent = operate(x, parseInt(y), parseInt(z));
  })
}

// Running event listeners on page

clickNumber();
clickOperator();
clickEquals(currentOperator, currentNumber, nextNumber);  
 *, *::before, *::after {
    box-sizing: border-box;
    font-family: Gotham Rounded, sans-serif;
    font-weight: 500;
}

body {
    background: linear-gradient(to right, #af8baf, #00909e);
    padding: 0;
    margin: 0;
}

/* Grid system set-up for calculator*/
.calculator {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr;
    padding: 10px;
    border-radius: 10px;

    /* Positioning of calculator */
    background-color: black;
    width: 300px;
    height: 400px;
    margin: auto;
    margin-top: 100px;
}

.span-two {
    grid-column: 1 / 3;
}

/* Calculator design*/

.output {
    grid-column: 1 / 5;
    background-color: black;
    color: white;
    font-size: 2rem;
    overflow-wrap: break-word;
    text-align: right;
}

button {
    font-size: 20px;
    border-radius: 5px;
    border-color: gray;
    background-color: gray;
    color: white;
    margin: 2px;
    outline: none;
}

button:active {
    background-color: lightgray;
}  
 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Calculator</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    
    <div class="calculator">
        <div class="output">
            
        </div>
        <button class="ac">AC</button>
        <button class="del">DEL</button>
        <button class="flip-sign"> /-</button>
        <button class="operator">÷</button>
        <button class="number">7</button>
        <button class="number">8</button>
        <button class="number">9</button>
        <button class="operator">×</button>
        <button class="number">4</button>
        <button class="number">5</button>
        <button class="number">6</button>
        <button class="operator">-</button>
        <button class="number">1</button>
        <button class="number">2</button>
        <button class="number">3</button>
        <button class="operator"> </button>
        <button class="number span-two">0</button>
        <button class="decimal">.</button>
        <button class="equals">=</button>
    </div>


    <script src="main.js"></script>
</body>
</html>  

Ответ №1:

Вам нужно проверить operatorActive , когда запускается прослушиватель щелчков. Вы проверяете это, когда добавляете слушателей при загрузке программы, и это всегда будет false в это время.

Аналогично, прослушиватель щелчков для = должен получить текущие значения всех переменных. Вы передаете начальные значения при вызове clickEquals() , они не меняются.

 // Functions for calculation ( , -, *, /)

const add = (a, b) => a   b;
const subtract = (a, b) => a - b;
const multiply = (a, b) => a * b;
const divide = (a, b) => a / b;

const operate = (operator, a, b) => {
  switch (operator) {
    case " ":
      return add(a, b);
    case "-":
      return subtract(a, b);
    case "×":
      return multiply(a, b);
    case "÷":
      return divide(a, b);
  }
};

// DOM selection of UI buttons and display

const numbers = document.querySelectorAll(".number");
const operators = document.querySelectorAll(".operator");
const equals = document.querySelector(".equals");
const display = document.querySelector(".output");

// Functions for event listeners when buttons clicked...

let currentNumber;
let currentOperator;
let nextNumber;
let operatorActive = false;

// ... for numerical buttons

function clickNumber() {
  numbers.forEach((number) => {
    number.addEventListener('click', () => {
      if (!operatorActive) {
        display.textContent  = number.textContent;
        currentNumber = display.textContent;
      } else {
        display.textContent  = number.textContent;
        nextNumber = display.textContent;
      }
    });
  });
}

// ... for operator buttons

function clickOperator() {
  operators.forEach((operator) => {
    operator.addEventListener('click', () => {
      currentOperator = operator.textContent;
      display.textContent = "";
      operatorActive = true;
    })
  });
}

// ... for equals button

function clickEquals() {
  equals.addEventListener('click', () => {
    operatorActive = false;
    // **below console logs are tests to see what values hold
    console.log(currentNumber);
    console.log(currentOperator);
    console.log(nextNumber);
    console.log(operatorActive);

    display.textContent = operate(currentOperator, parseInt(currentNumber), parseInt(nextNumber));
  })
}

// Running event listeners on page

clickNumber();
clickOperator();
clickEquals();  
 *,
*::before,
*::after {
  box-sizing: border-box;
  font-family: Gotham Rounded, sans-serif;
  font-weight: 500;
}

body {
  background: linear-gradient(to right, #af8baf, #00909e);
  padding: 0;
  margin: 0;
}


/* Grid system set-up for calculator*/

.calculator {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr;
  padding: 10px;
  border-radius: 10px;
  /* Positioning of calculator */
  background-color: black;
  width: 300px;
  height: 400px;
  margin: auto;
  margin-top: 100px;
}

.span-two {
  grid-column: 1 / 3;
}


/* Calculator design*/

.output {
  grid-column: 1 / 5;
  background-color: black;
  color: white;
  font-size: 2rem;
  overflow-wrap: break-word;
  text-align: right;
}

button {
  font-size: 20px;
  border-radius: 5px;
  border-color: gray;
  background-color: gray;
  color: white;
  margin: 2px;
  outline: none;
}

button:active {
  background-color: lightgray;
}  
 <!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Calculator</title>
  <link rel="stylesheet" href="styles.css">
</head>

<body>

  <div class="calculator">
    <div class="output">

    </div>
    <button class="ac">AC</button>
    <button class="del">DEL</button>
    <button class="flip-sign"> /-</button>
    <button class="operator">÷</button>
    <button class="number">7</button>
    <button class="number">8</button>
    <button class="number">9</button>
    <button class="operator">×</button>
    <button class="number">4</button>
    <button class="number">5</button>
    <button class="number">6</button>
    <button class="operator">-</button>
    <button class="number">1</button>
    <button class="number">2</button>
    <button class="number">3</button>
    <button class="operator"> </button>
    <button class="number span-two">0</button>
    <button class="decimal">.</button>
    <button class="equals">=</button>
  </div>


  <script src="main.js"></script>
</body>

</html>  

Ответ №2:

Ваша главная проблема здесь:

 function clickNumber() {
  numbers.forEach((number) => {
    if (!operatorActive) {
      number.addEventListener('click', () => {
        display.textContent  = number.textContent;
        currentNumber = display.textContent;
      })
    } else if (operatorActive) {
      number.addEventListener('click', () => {
        display.textContent  = number.textContent;
        nextNumber = display.textContent;
      })
    }
  });
}
  

Вы вызываете эту функцию в начале, чтобы настроить слушателей на числа, но в этот момент operatorActive всегда false . Таким образом, все числа получают только первого слушателя и всегда действуют так, как будто ни один оператор не активен. Я думаю, вы хотите что-то вроде:

 function clickNumber() {
  numbers.forEach((number) => {
    number.addEventListener('click', () => {
      if (!operatorActive) {
        display.textContent  = number.textContent;
        currentNumber = display.textContent;
      } else {
        display.textContent  = number.textContent;
        nextNumber = display.textContent;
      }
    });
  });
}