Введение
Создание калькулятора – это отличный способ освоить базовые принципы JavaScript и работу с DOM-элементами. В этой статье мы разберем, как создать простой, но функциональный калькулятор, способный выполнять основные математические операции. Наш калькулятор будет иметь понятный интерфейс и обрабатывать все базовые арифметические действия.
Пример:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Простой Калькулятор</title>
<style>
.calculator {
border: 1px solid #ccc;
border-radius: 5px;
width: 400px;
padding: 10px;
}
.calculator-screen {
width: 100%;
height: 50px;
font-size: 2em;
text-align: right;
margin-bottom: 10px;
}
.calculator-keys {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
button {
padding: 20px;
font-size: 1.2em;
border: 1px solid #ccc;
border-radius: 5px;
cursor: pointer;
}
.operator {
background-color: #f0f0f0;
}
.equal-sign {
background-color: #4CAF50;
color: white;
grid-row: span 2;
}
</style>
</head>
<body>
<div class="calculator">
<input type="text" class="calculator-screen" value="0" 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="*">×</button>
<button type="button" class="operator" value="/">÷</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="4">4</button>
<button type="button" value="5">5</button>
<button type="button" value="6">6</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="0">0</button>
<button type="button" class="decimal" value=".">.</button>
<button type="button" class="all-clear" value="all-clear">AC</button>
<button type="button" class="equal-sign" value="=">=</button>
</div>
</div>
<script>
const calculator = {
displayValue: '0',
firstOperand: null,
waitingForSecondOperand: false,
operator: null,
};
function inputDigit(digit) {
const { displayValue, waitingForSecondOperand } = calculator;
if (waitingForSecondOperand === true) {
calculator.displayValue = digit;
calculator.waitingForSecondOperand = false;
} else {
calculator.displayValue = displayValue === '0' ? digit : displayValue + digit;
}
}
function inputDecimal(dot) {
if (calculator.waitingForSecondOperand === true) {
calculator.displayValue = '0.';
calculator.waitingForSecondOperand = false;
return;
}
if (!calculator.displayValue.includes(dot)) {
calculator.displayValue += dot;
}
}
function handleOperator(nextOperator) {
const { firstOperand, displayValue, operator } = calculator;
const inputValue = parseFloat(displayValue);
if (firstOperand === null) {
calculator.firstOperand = inputValue;
}
calculator.waitingForSecondOperand = true;
calculator.operator = nextOperator;
}
function calculate() {
const secondOperand = parseFloat(calculator.displayValue);
const firstOperand = calculator.firstOperand;
const operator = calculator.operator;
if (operator === null || firstOperand === null) {
return;
}
let result;
switch (operator) {
case '+':
result = firstOperand + secondOperand;
break;
case '-':
result = firstOperand - secondOperand;
break;
case '*':
result = firstOperand * secondOperand;
break;
case '/':
result = firstOperand / secondOperand;
break;
default:
return;
}
calculator.displayValue = String(result);
calculator.firstOperand = result;
calculator.operator = null;
calculator.waitingForSecondOperand = false;
}
function resetCalculator() {
calculator.displayValue = '0';
calculator.firstOperand = null;
calculator.waitingForSecondOperand = false;
calculator.operator = null;
}
const keys = document.querySelector('.calculator-keys');
keys.addEventListener('click', event => {
const { target } = event;
if (!target.matches('button')) {
return;
}
if (target.classList.contains('operator')) {
handleOperator(target.value);
updateDisplay();
return;
}
if (target.classList.contains('decimal')) {
inputDecimal(target.value);
updateDisplay();
return;
}
if (target.classList.contains('all-clear')) {
resetCalculator();
updateDisplay();
return;
}
if (target.classList.contains('equal-sign')) {
calculate();
updateDisplay();
return;
}
inputDigit(target.value);
updateDisplay();
});
function updateDisplay() {
const display = document.querySelector('.calculator-screen');
display.value = calculator.displayValue;
}
</script>
</body>
</html>
HTML структура
<div class="calculator">
<input type="text" class="calculator-screen" value="0" 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="*">×</button>
<button type="button" class="operator" value="/">÷</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" value=".">.</button>
<button type="button" class="all-clear" value="all-clear">AC</button>
<button type="button" class="equal-sign" value="=">=</button>
</div>
</div>
CSS стили
.calculator {
border: 1px solid #ccc;
border-radius: 5px;
width: 400px;
padding: 10px;
}
.calculator-screen {
width: 100%;
height: 50px;
font-size: 2em;
text-align: right;
margin-bottom: 10px;
}
.calculator-keys {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
button {
padding: 20px;
font-size: 1.2em;
border: 1px solid #ccc;
border-radius: 5px;
cursor: pointer;
}
.operator {
background-color: #f0f0f0;
}
.equal-sign {
background-color: #4CAF50;
color: white;
grid-row: span 2;
}
JavaScript логика
const calculator = {
displayValue: '0',
firstOperand: null,
waitingForSecondOperand: false,
operator: null,
};
function inputDigit(digit) {
const { displayValue, waitingForSecondOperand } = calculator;
if (waitingForSecondOperand === true) {
calculator.displayValue = digit;
calculator.waitingForSecondOperand = false;
} else {
calculator.displayValue = displayValue === '0' ? digit : displayValue + digit;
}
}
function inputDecimal(dot) {
if (calculator.waitingForSecondOperand === true) {
calculator.displayValue = '0.';
calculator.waitingForSecondOperand = false;
return;
}
if (!calculator.displayValue.includes(dot)) {
calculator.displayValue += dot;
}
}
function handleOperator(nextOperator) {
const { firstOperand, displayValue, operator } = calculator;
const inputValue = parseFloat(displayValue);
if (firstOperand === null) {
calculator.firstOperand = inputValue;
}
calculator.waitingForSecondOperand = true;
calculator.operator = nextOperator;
}
function calculate() {
const secondOperand = parseFloat(calculator.displayValue);
const firstOperand = calculator.firstOperand;
const operator = calculator.operator;
if (operator === null || firstOperand === null) {
return;
}
let result;
switch (operator) {
case '+':
result = firstOperand + secondOperand;
break;
case '-':
result = firstOperand - secondOperand;
break;
case '*':
result = firstOperand * secondOperand;
break;
case '/':
result = firstOperand / secondOperand;
break;
default:
return;
}
calculator.displayValue = String(result);
calculator.firstOperand = result;
calculator.operator = null;
calculator.waitingForSecondOperand = false;
}
function resetCalculator() {
calculator.displayValue = '0';
calculator.firstOperand = null;
calculator.waitingForSecondOperand = false;
calculator.operator = null;
}
const keys = document.querySelector('.calculator-keys');
keys.addEventListener('click', event => {
const { target } = event;
if (!target.matches('button')) {
return;
}
if (target.classList.contains('operator')) {
handleOperator(target.value);
updateDisplay();
return;
}
if (target.classList.contains('decimal')) {
inputDecimal(target.value);
updateDisplay();
return;
}
if (target.classList.contains('all-clear')) {
resetCalculator();
updateDisplay();
return;
}
if (target.classList.contains('equal-sign')) {
calculate();
updateDisplay();
return;
}
inputDigit(target.value);
updateDisplay();
});
function updateDisplay() {
const display = document.querySelector('.calculator-screen');
display.value = calculator.displayValue;
}
Объяснение кода
В нашем калькуляторе мы использовали три основных компонента: HTML для структуры, CSS для стилизации и JavaScript для функциональности. HTML-структура представляет собой контейнер с экраном калькулятора и сеткой кнопок. CSS-стили организуют элементы в привлекательный интерфейс с использованием CSS Grid для расположения кнопок.
JavaScript-код построен на объекте calculator, который хранит текущее состояние калькулятора. Основные функции:
- inputDigit: обрабатывает ввод цифр
- inputDecimal: добавляет десятичную точку
- handleOperator: управляет математическими операциями
- calculate: выполняет вычисления
Заключение
Создание калькулятора – это не только практическое упражнение в программировании, но и отличный способ понять основы работы с пользовательским интерфейсом и обработкой событий в JavaScript. Этот проект можно расширять, добавляя новые функции, такие как поддержка клавиатуры, дополнительные математические операции или историю вычислений. Главное – понимать базовые принципы, которые мы разобрали в этой статье.