Как вернуть логическое значение, используя indexOf () вместо include ()? - PullRequest
0 голосов
/ 27 апреля 2020

Я выполняю задачу калькулятора, и когда я начинаю решать часть десятичной точки, это дает мне неожиданное поведение. Я сделал функцию с именем input di git, чтобы при нажатии клавиши десятичной точки мне нужно было добавить десятичную точку к числу, которое уже существует на дисплее. Внутри функции я использовал оператор if, чтобы проверить, не содержит ли свойство объекта точку, используя (...)indexOf(dot) === -1 или !(...).includes(dot), в противном случае я добавлю к этому объекту свойства точку. Но результат в браузере, когда я нажимаю на точку, он показывает мне две точки вместо одной, и мне было интересно, что я делаю неправильно.

Это мой код до сих пор:

const calculator = {
  displayValue: '0',
  firstOperand: null,
  waitingForSecondOperand: false,
  operator: null
};

function inputDigit(digit) {

  const {
    displayValue
  } = calculator;
  calculator.displayValue = displayValue === '0' ? digit : displayValue + digit;

}

//*here is the function that adds a dot* 
function inputDecimal(dot) {
  if (!calculator.displayValue.includes(dot)) {
    calculator.displayValue += dot;
  }
}

function updateDisplay() {
  const display = document.querySelector('#screen');
  display.value = calculator.displayValue;
}

updateDisplay();

const keys = document.querySelector('.calculator-keys');

keys.addEventListener('click', (e) => {

  const {
    target
  } = e; // is equivalent to const target = event.target;

  if (!target.matches('button')) {
    return;
  }

  if (target.classList.contains('operator')) {
    console.log('operator', target.value);
    return;
  }

  if (target.classList.contains('decimal')) {
    inputDecimal(target.value);
    updateDisplay();

  }

  if (target.classList.contains('all-clear')) {
    console.log('clear', target.value);
    return;
  }

  inputDigit(target.value);
  // /
  updateDisplay();

});
html {
  font-size: 62.5%;
  box-sizing: border-box;
}

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: inherit;
}

.calculator {
  border: 1px solid #ccc;
  border-radius: 5px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 400px;
}

.calculator-screen {
  width: 100%;
  font-size: 5rem;
  height: 80px;
  border: none;
  background-color: #252525;
  color: #fff;
  text-align: right;
  padding-right: 20px;
  padding-left: 10px;
}

button {
  height: 60px;
  background-color: #fff;
  border-radius: 3px;
  border: 1px solid #c4c4c4;
  background-color: transparent;
  font-size: 2rem;
  color: #333;
  background-image: linear-gradient(to bottom, transparent, transparent 50%, rgba(0, 0, 0, .04));
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .05), inset 0 1px 0 0 rgba(255, 255, 255, .45), inset 0 -1px 0 0 rgba(255, 255, 255, .15), 0 1px 0 0 rgba(255, 255, 255, .15);
  text-shadow: 0 1px rgba(255, 255, 255, .4);
}

button:hover {
  background-color: #eaeaea;
}

.operator {
  color: #337cac;
}

.all-clear {
  background-color: #f0595f;
  border-color: #b0353a;
  color: #fff;
}

.all-clear:hover {
  background-color: #f17377;
}

.equal-sign {
  background-color: #2e86c0;
  border-color: #337cac;
  color: #fff;
  height: 100%;
  grid-area: 2 / 4 / 6 / 5;
}

.equal-sign:hover {
  background-color: #4e9ed4;
}

.calculator-keys {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-gap: 20px;
  padding: 20px;
}
<div class="calculator">

  <input type="text" id="screen" class="calculator-screen" value="" disabled />
  <div class="calculator-keys">

    <button type="button" class="operator" value="+">+</button>
    <button type="button" class="operator" value="-">-</button>
    <button type="button" class="operator" value="*">&times;</button>
    <button type="button" class="operator" value="/">&divide;</button>

    <button type="button" value="7">7</button>
    <button type="button" value="8">8</button>
    <button type="button" value="9">9</button>

    <button type="button" value="4">4</button>
    <button type="button" value="5">5</button>
    <button type="button" value="6">6</button>

    <button type="button" value="1">1</button>
    <button type="button" value="2">2</button>
    <button type="button" value="3">3</button>

    <button type="button" value="0">0</button>
    <button type="button" class="decimal function" value=".">.</button>
    <button type="button" class="all-clear function" value="all-clear">AC</button>

    <button type="button" class="equal-sign operator" value="=">=</button>

  </div>

</div>

1 Ответ

1 голос
/ 27 апреля 2020

В вашем коде addEventListener, поскольку вы обрабатываете все случаи, кроме чисел, для всех слушателей событий будет вызываться функция inputDigit(target.value) для каждого типа нажатия кнопки, будь то число, десятичное число или оператор. Следовательно, при добавлении десятичной дроби есть две функции, которые называются inputDecimal и inputDigit, поэтому вы получаете два десятичных знака при каждом нажатии десятичной кнопки.

Чтобы избежать этого, вы можете просто добавить класс 'di git' для всех ваших входов di git, как показано ниже

  <button type="button" value="1" class="digit">1</button>
  <button type="button" value="2" class="digit">2</button>
  <button type="button" value="3" class="digit">3</button>

И в прослушивателе событий вы можете добавить следующее код

if (target.classList.contains('digit')) {
  inputDigit(target.value);
  updateDisplay();
}

Полный код для HTML:

<div class="calculator">
  <input type="text" id="screen" class="calculator-screen" value="" disabled />
  <div class="calculator-keys">
    <button type="button" class="operator" value="+">+</button>
    <button type="button" class="operator" value="-">-</button>
    <button type="button" class="operator" value="*">&times;</button>
    <button type="button" class="operator" value="/">&divide;</button>

    <button type="button" value="7" class="digit">7</button>
    <button type="button" value="8" class="digit">8</button>
    <button type="button" value="9" class="digit">9</button>

    <button type="button" value="4" class="digit">4</button>
    <button type="button" value="5" class="digit">5</button>
    <button type="button" value="6" class="digit">6</button>

    <button type="button" value="1" class="digit">1</button>
    <button type="button" value="2" class="digit">2</button>
    <button type="button" value="3" class="digit">3</button>

    <button type="button" value="0" class="digit">0</button>
    <button type="button" class="decimal function" value=".">.</button>
    <button type="button" class="all-clear function" value="all-clear">AC</button>

    <button type="button" class="equal-sign operator" value="=">=</button>

  </div>

</div>

И код JavaScript:

<script>
  const calculator = {
    displayValue: '0',
    firstOperand: null,
    waitingForSecondOperand: false,
    operator: null
  };

  function inputDigit(digit) {

    const { displayValue } = calculator;
    calculator.displayValue = displayValue === '0' ? digit : displayValue + digit;
  }

  function inputDecimal(dot) {
    if (!calculator.displayValue.includes(dot)) {
      calculator.displayValue += dot;
    }
  }

  function updateDisplay() {
    const display = document.querySelector('#screen');
    display.value = calculator.displayValue;
  }

  updateDisplay();

  const keys = document.querySelector('.calculator-keys');

  keys.addEventListener('click', (e) => {
    const { target } = e; // is equivalent to const target = event.target;
    if (!target.matches('button')) {
      return;
    }
    if (target.classList.contains('operator')) {
      return;
    }
    if (target.classList.contains('decimal')) {
      inputDecimal(target.value);
      updateDisplay();
    }
    if (target.classList.contains('all-clear')) {
      console.log('clear', target.value);
      return;
    }
    if (target.classList.contains('digit')) {
      inputDigit(target.value);
      updateDisplay();
    }
  });
</script>
...