🎯 Цель урока
В этом уроке мы оживим наш калькулятор с помощью JavaScript! Научимся обрабатывать нажатия кнопок, выполнять математические операции и управлять отображением. Создадим полнофункциональный калькулятор с обработкой ошибок.
💡 Что вы узнаете:
• Переменные и управление состоянием
• Функции для математических операций
• Обработку событий и DOM манипуляции
• Работу с eval() и обработку ошибок
• Логику калькулятора и пользовательский ввод
📚 JavaScript концепции
Переменные для хранения состояния калькулятора. let - изменяемые, const - константы
Функции для выполнения математических операций и управления интерфейсом
Получение доступа к HTML элементам для изменения их содержимого
Выполнение математических выражений из строки. Осторожно - может быть опасно!
Обработка ошибок для предотвращения "поломки" приложения
🔧 Переменные состояния
Начнём с создания переменных для хранения состояния калькулятора:
// Переменные для калькулятора
let calcDisplay = '0';
let shouldResetDisplay = false;
let currentMode = 'calc'; // 'calc' или 'quest'
// Получаем ссылки на HTML элементы
const displayElement = document.getElementById('calcDisplay');
const calculatorSection = document.getElementById('calculator-section');
const questSection = document.getElementById('quest-section');
calcDisplay хранит то, что показывается на экране. shouldResetDisplay определяет, нужно ли очистить дисплей при следующем вводе
🔢 Функции работы с числами
Создаём функцию для добавления цифр и операторов:
function appendToCalc(value) {
// Если нужно сбросить дисплей после вычисления
if (shouldResetDisplay) {
calcDisplay = '';
shouldResetDisplay = false;
}
// Если дисплей показывает '0' и вводим не точку
if (calcDisplay === '0' && value !== '.') {
calcDisplay = value;
} else {
calcDisplay += value;
}
// Обновляем отображение на экране
updateCalcDisplay();
}
function updateCalcDisplay() {
displayElement.textContent = calcDisplay;
}
🔍 Логика функции:
• Проверяем, нужно ли сбросить дисплей
• Заменяем '0' на новую цифру или добавляем к существующему
числу
• Обновляем HTML элемент дисплея
• Сбрасываем флаг reset после использования
🧹 Функции очистки
Создаём функции для очистки и удаления символов:
function clearCalc() {
calcDisplay = '0';
shouldResetDisplay = false;
updateCalcDisplay();
}
function deleteLast() {
// Если на дисплее только один символ или '0'
if (calcDisplay.length <= 1 || calcDisplay === '0') {
calcDisplay = '0';
} else {
// Удаляем последний символ
calcDisplay = calcDisplay.slice(0, -1);
}
updateCalcDisplay();
}
Метод slice удаляет последний символ из строки. 0 - начало, -1 - предпоследний символ
🧮 Вычисление результата
Самая важная функция - выполнение математических операций:
function calculateResult() {
try {
// Заменяем символ умножения для eval()
let expression = calcDisplay.replace(/×/g, '*');
// Проверяем, что выражение не пустое
if (!expression || expression === '0') {
return;
}
// Вычисляем результат
let result = eval(expression);
// Проверяем на деление на ноль
if (!isFinite(result)) {
calcDisplay = 'Ошибка';
shouldResetDisplay = true;
updateCalcDisplay();
return;
}
// Округляем до 10 знаков после запятой
result = Math.round(result * 10000000000) / 10000000000;
calcDisplay = result.toString();
shouldResetDisplay = true;
updateCalcDisplay();
} catch (error) {
// Обрабатываем ошибки вычисления
calcDisplay = 'Ошибка';
shouldResetDisplay = true;
updateCalcDisplay();
}
}
⚠️ Безопасность eval():
• eval() выполняет любой JavaScript код, что может быть опасно
• Мы используем его только для математических выражений
• В реальных проектах лучше использовать специальные библиотеки
• try...catch защищает от ошибок выполнения
🎮 Переключение режимов
Функция для переключения между калькулятором и квестами:
function setMode(mode) {
currentMode = mode;
// Удаляем класс active у всех кнопок
document.querySelectorAll('.mode-btn').forEach(btn => {
btn.classList.remove('active');
});
// Добавляем класс active к нажатой кнопке
document.getElementById(mode + '-mode').classList.add('active');
// Показываем/скрываем соответствующие секции
if (mode === 'quest') {
questSection.style.display = 'block';
calculatorSection.style.display = 'none';
} else {
questSection.style.display = 'none';
calculatorSection.style.display = 'block';
}
}
Находит все элементы с указанным селектором. forEach() применяет функцию к каждому найденному элементу
⌨️ Поддержка клавиатуры
Добавим возможность использовать клавиатуру для ввода:
// Обработка нажатий клавиш
document.addEventListener('keydown', function(event) {
// Только если активен режим калькулятора
if (currentMode !== 'calc') return;
const key = event.key;
// Обрабатываем цифры
if ('0123456789'.includes(key)) {
appendToCalc(key);
}
// Обрабатываем операторы
else if ('+-*/'.includes(key)) {
const operator = key === '*' ? '×' : key;
appendToCalc(operator);
}
// Обрабатываем точку
else if (key === '.') {
appendToCalc('.');
}
// Enter или = для вычисления
else if (key === 'Enter' || key === '=') {
event.preventDefault();
calculateResult();
}
// Backspace для удаления
else if (key === 'Backspace') {
event.preventDefault();
deleteLast();
}
// Escape для очистки
else if (key === 'Escape') {
clearCalc();
}
});
🎮 Интерактивная демонстрация
Попробуй наш работающий калькулятор прямо здесь:
🧮 Рабочий калькулятор
Попробуй вычислить: 15 × 4 + 8 🧮
🔧 Инициализация приложения
Код для запуска приложения при загрузке страницы:
// Инициализация при загрузке страницы
document.addEventListener('DOMContentLoaded', function() {
// Устанавливаем начальный режим
setMode('quest');
// Обновляем дисплей калькулятора
updateCalcDisplay();
// Добавляем эффекты при загрузке
document.querySelector('.game-container').style.opacity = '0';
setTimeout(() => {
document.querySelector('.game-container').style.transition = 'opacity 0.5s';
document.querySelector('.game-container').style.opacity = '1';
}, 100);
console.log('🧮 Математическое приложение загружено!');
});
Событие, которое срабатывает когда HTML полностью загружен. Лучшее место для инициализации JavaScript
🐛 Обработка ошибок
Добавим более детальную обработку различных ошибок:
function safeCalculate(expression) {
// Проверяем на пустое выражение
if (!expression || expression.trim() === '') {
return { error: 'Пустое выражение' };
}
// Проверяем на недопустимые символы
const allowedChars = /^[0-9+\-*/().×\s]+$/;
if (!allowedChars.test(expression)) {
return { error: 'Недопустимые символы' };
}
// Проверяем на последовательные операторы
if (/[+\-*/×]{2,}/.test(expression)) {
return { error: 'Неправильное выражение' };
}
try {
const cleanExpression = expression.replace(/×/g, '*');
const result = eval(cleanExpression);
if (!isFinite(result)) {
return { error: 'Деление на ноль' };
}
return { result: result };
} catch (error) {
return { error: 'Ошибка вычисления' };
}
}
🎓 Итоги урока
- Переменные: Научились управлять состоянием калькулятора
- Функции: Создали модульную архитектуру кода
- DOM: Научились изменять содержимое HTML элементов
- События: Обрабатываем клики мыши и нажатия клавиш
- Математика: Выполняем вычисления с помощью eval()
- Ошибки: Предотвращаем "поломку" приложения
🚀 Что дальше?
В следующем уроке мы создадим систему математических квестов с разными уровнями сложности, статистикой и системой очков для геймификации обучения!