Калькулятор на JS с скобками

const buttons = document.querySelectorAll('button');


const display = document.querySelector('.display');

   

buttons.forEach(function(button) {
  button.addEventListener('click', calculate);
});



function calculate(event) {
  


  const clickedButtonValue = event.target.value;

  if (clickedButtonValue === '=') {
    


    if (display.value !== '') {
      


      display.value = eval(display.value);
    }
  } else if (clickedButtonValue === 'C') {
    


    display.value = '';
  } else {
    


    display.value += clickedButtonValue;
  }
}
* {
    padding: 0;
    margin: 0;
  }
  
  body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #222831;
    font-family: sans-serif;
  }
  .calculator {
    width: 300px;
    padding-bottom: 15px;
    border-radius: 7px;
    background-color: #000;
    box-shadow: 5px 8px 8px -2px rgba(0, 0, 0, 0.61);
  }
  .display {
    width: 100%;
    height: 80px;
    border: none;
    box-sizing: border-box;
    padding: 10px;
    font-size: 2rem;
    background-color: #00ff44;
    color: #000;
    text-align: right;
    border-top-left-radius: 7px;
    border-top-right-radius: 7px;
  }
  .row {
    display: flex;
    justify-content: space-between;
  }
 
  
  button {
    width: 50px;  
    height: 50px;
    border-radius: 50%;
    border: none;
    outline: none;
    font-size: 1.5rem;
    background-color: #222;
    color: #fff;
    margin: 10px;
  }
  
  button:hover {
    cursor: pointer;
  }
  

  
  .operator {
    background-color: #00ff44;
    color: #000;
  }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" type="text/css" href="css/styles.css">
  <title>Calculator</title>
</head>
<body>

  
<!-- calculator -->

  <div class="calculator">

    
<!-- display -->

    <input type="text" class="display" disabled>
    
<!-- keys -->

    <div class="keys">
      
<!-- 4 rows of keys -->

      <div class="row">
        <button value="7">7</button>
        <button value="8">8</button>
        <button value="9">9</button>
        <button value="+" class="operator">+</button>
      </div>
      <div class="row">
        <button value="4">4</button>
        <button value="5">5</button>
        <button value="6">6</button>
        <button value="-" class="operator">-</button>
      </div>
      <div class="row">
        <button value="1">1</button>
        <button value="2">2</button>
        <button value="3">3</button>
        <button value="*" class="operator">*</button>
      </div>
      <div class="row">
        <button value="C" class="operator">C</button>
        <button value="0">0</button>
        <button value="/" class="operator">/</button>
        <button value="=" class="operator">=</button>
      </div>
      <div class="row">
        <button value="(" class="operator">(</button>
        <button value=")" class="operator">)</button>
        <button value="^" class="operator">^</button>
        <button value="%" class="operator">%</button>
      </div>
    </div>

  </div>
  
<!-- calculator body ends -->

  
  <script type="text/javascript" src="js/scripts.js"></script>
</body>
</html>

Добрый день как можно в этот добавить скобки а,также вычесление степени и процента никак не получается


Ответы (2 шт):

Автор решения: Aziz Umarov

Конечно предупреждаю что eval страшная функция и нужно быть с ней максимально аккуратно. (считаю что вы учитесь и никогда такое не пойдет куда либо)

Для возведения в степень замените ^ на **, так как оператор ^ в JS это Исключающее или (XOR). Получится что-то вроде eval(display.value.replaceAll('^', '**'))

по процентам дополните вопрос с примером и ожиданием. Если подсмотреть у @OPTIMUSPRIME будет как-то так

eval(display.value.replaceAll('^', '**').replaceAll('%', '*(1/100)'))

→ Ссылка
Автор решения: OPTIMUS PRIME

Символ ^ в JS - это исключающее "или" (XOR). Если и так используете eval, можно перед его вызовом банально заменить все ^ из строки на ** - оператор степени.

.replace(/\^/g, "**")


А a % b - дает остаток от деления a на b. Его в свою очередь нужно заменить
% b* (b / 100)

.replace(/%(\d+(?:\.\d+)?)/g, "*($1/100)"); — в будущей строке, $1 ссылается на совпадение внутри первых скобок из регулярного выражения (т.е. на число (\d+(?:\.\d+)?))

►► https://regex101.com/

const buttons = document.querySelectorAll('button');
const display = document.querySelector('.display');

buttons.forEach(function(button) {
  button.addEventListener('click', calculate);
});

function calculate(event) {
  const clickedButtonValue = event.target.value;

  if (clickedButtonValue === '=') {  
    if (display.value !== '') {
      let str = display.value
        .replace(/\^/g, "**")
        .replace(/%(\d+(?:\.\d+)?)/g, "*($1/100)");        
        
      display.value = eval( str );
    }    
  } else if (clickedButtonValue === 'C') {  
    display.value = '';
  } else {
    display.value += clickedButtonValue;
  }
}
* {
  padding: 0;
  margin: 0;
}

body {
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #222831;
  font-family: sans-serif;
}

.calculator {
  width: 300px;
  padding-bottom: 15px;
  border-radius: 7px;
  background-color: #000;
  box-shadow: 5px 8px 8px -2px rgba(0, 0, 0, 0.61);
}

.display {
  width: 100%;
  height: 80px;
  border: none;
  box-sizing: border-box;
  padding: 10px;
  font-size: 2rem;
  background-color: #00ff44;
  color: #000;
  text-align: right;
  border-top-left-radius: 7px;
  border-top-right-radius: 7px;
}

.row {
  display: flex;
  justify-content: space-between;
}

button {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  border: none;
  outline: none;
  font-size: 1.5rem;
  background-color: #222;
  color: #fff;
  margin: 10px;
}

button:hover {
  cursor: pointer;
}

.operator {
  background-color: #00ff44;
  color: #000;
}
<!DOCTYPE html>
<html lang="en">

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

<body>


  <!-- calculator -->

  <div class="calculator">


    <!-- display -->

    <input type="text" class="display" disabled>

    <!-- keys -->

    <div class="keys">

      <!-- 4 rows of keys -->

      <div class="row">
        <button value="7">7</button>
        <button value="8">8</button>
        <button value="9">9</button>
        <button value="+" class="operator">+</button>
      </div>
      <div class="row">
        <button value="4">4</button>
        <button value="5">5</button>
        <button value="6">6</button>
        <button value="-" class="operator">-</button>
      </div>
      <div class="row">
        <button value="1">1</button>
        <button value="2">2</button>
        <button value="3">3</button>
        <button value="*" class="operator">*</button>
      </div>
      <div class="row">
        <button value="C" class="operator">C</button>
        <button value="0">0</button>
        <button value="/" class="operator">/</button>
        <button value="=" class="operator">=</button>
      </div>
      <div class="row">
        <button value="(" class="operator">(</button>
        <button value=")" class="operator">)</button>
        <button value="^" class="operator">^</button>
        <button value="%" class="operator">%</button>
      </div>
    </div>

  </div>

  <!-- calculator body ends -->


  <script type="text/javascript" src="js/scripts.js"></script>
</body>

</html>

Но можно разбирать строку и без eval) Вполне подходящая задача, чтобы "набить руку" на регулярных выражениях - Подсчет арифметических операций из строки без функции eval() (под вопросом см. ссылки на другие алгоритмы)

→ Ссылка