/
Coderdev
/
web-static-labs
Обзор
Документация
Войти
/
Coderdev
/
web-static-labs
Код
Запросы
0
Задачи
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
html/lab5/task5/script.js
278 строк
9 KB
unknown
1
31 мар 2026, 12:08
31 мар 2026, 12:08
f86fbc2
Код
Авторство
О чём код?
'use strict'; document.addEventListener('DOMContentLoaded', () => { // Элементы const screen = document.getElementById('screen'); const statusEl = document.getElementById('status'); const roundCheckbox = document.getElementById('roundCheckbox'); const logBaseContainer = document.getElementById('logBaseContainer'); const logBaseInput = document.getElementById('logBase'); const keypad = document.querySelector('.keypad'); // Состояние калькулятора let displayValue = '0'; // То, что видно на экране (выражение или число) let currentInput = '0'; // Текущее вводимое число let expression = []; // Массив для хранения цепочки: [число, операнд, число, операнд...] let waitingForNewNumber = false; // Флаг: ждем ли ввода нового числа после операции let isUnaryOperation = false; // Флаг унарной операции (√, log) let unaryOpPending = null; // Какая унарная операция выбрана // Обновление экрана function updateScreen() { // Если есть выражение, показываем его, иначе текущее число if (expression.length > 0) { screen.textContent = expression.join(' ') + ' ' + currentInput; } else { screen.textContent = currentInput; } } // Показать ошибку function showError(message) { statusEl.textContent = message; setTimeout(() => { statusEl.textContent = ''; }, 3000); } // Очистка ошибки function clearError() { statusEl.textContent = ''; } // Полная очистка (Кнопка C) function clearAll() { displayValue = '0'; currentInput = '0'; expression = []; waitingForNewNumber = false; isUnaryOperation = false; unaryOpPending = null; keypad.classList.remove('locked'); logBaseContainer.classList.add('hidden'); logBaseInput.value = ''; updateScreen(); clearError(); } // Обработка цифр function appendNumber(num) { // Если активна унарная операция, блокируем ввод второго операнда if (isUnaryOperation) { showError('Ввод второго операнда заблокирован'); return; } if (waitingForNewNumber) { currentInput = ''; waitingForNewNumber = false; } if (num === '.' && currentInput.includes('.')) return; if (currentInput === '0' && num !== '.') { currentInput = num; } else { currentInput += num; } updateScreen(); clearError(); } // Обработка бинарных операций (+, -, *, /) function setBinaryOp(op) { // Если была унарная операция, сначала выполним её if (isUnaryOperation && unaryOpPending) { calculateUnary(); if (statusEl.textContent) return; // Если ошибка, выходим } // Если уже ждем новое число, просто меняем операцию в выражении if (waitingForNewNumber) { if (expression.length > 0) { expression[expression.length - 1] = op; } updateScreen(); return; } // Добавляем текущее число и операцию в выражение expression.push(currentInput); expression.push(op); waitingForNewNumber = true; currentInput = '0'; isUnaryOperation = false; unaryOpPending = null; keypad.classList.remove('locked'); logBaseContainer.classList.add('hidden'); updateScreen(); } // Обработка унарных операций (√, log) function setUnaryOp(op) { // Если есть выражение, сначала вычислим его if (expression.length > 0 && !waitingForNewNumber) { calculateResult(); if (statusEl.textContent) return; } unaryOpPending = op; isUnaryOperation = true; waitingForNewNumber = false; // Не сбрасываем, берем текущее число keypad.classList.add('locked'); // Блокируем ввод цифр if (op === 'log') { logBaseContainer.classList.remove('hidden'); logBaseInput.focus(); } else { logBaseContainer.classList.add('hidden'); } updateScreen(); } // Вычисление унарной операции function calculateUnary() { const a = parseFloat(currentInput); let result = NaN; if (isNaN(a)) { showError('Введите число'); return false; } if (unaryOpPending === 'sqrt') { if (a < 0) { showError('Корень из отрицательного числа'); return false; } result = Math.sqrt(a); } else if (unaryOpPending === 'log') { const base = parseFloat(logBaseInput.value); if (isNaN(base) || base <= 0 || base === 1) { showError('Основание x > 0 и x ≠ 1'); return false; } if (a <= 0) { showError('Логарифм из числа ≤ 0'); return false; } result = Math.log(a) / Math.log(base); } // Округление if (roundCheckbox.checked && !isNaN(result)) { result = Math.round(result * 1000) / 1000; } currentInput = String(result); expression = []; // Очищаем выражение, так как операция выполнена isUnaryOperation = false; unaryOpPending = null; waitingForNewNumber = true; keypad.classList.remove('locked'); logBaseContainer.classList.add('hidden'); logBaseInput.value = ''; updateScreen(); clearError(); return true; } // Вычисление результата бинарного выражения (=) function calculateResult() { // Если висит унарная операция if (isUnaryOperation && unaryOpPending) { calculateUnary(); return; } // Если выражение пустое, ничего не делаем if (expression.length === 0) return; // Добавляем последнее число в выражение expression.push(currentInput); // Вычисляем всё выражение слева направо let result = parseFloat(expression[0]); for (let i = 1; i < expression.length; i += 2) { const op = expression[i]; const nextNum = parseFloat(expression[i + 1]); if (isNaN(nextNum)) { showError('Ошибка в выражении'); return; } switch (op) { case '+': result += nextNum; break; case '-': result -= nextNum; break; case '*': result *= nextNum; break; case '/': if (nextNum === 0) { showError('Деление на ноль'); return; } result /= nextNum; break; default: showError('Неизвестная операция'); return; } } // Округление if (roundCheckbox.checked && !isNaN(result)) { result = Math.round(result * 1000) / 1000; } currentInput = String(result); expression = []; waitingForNewNumber = true; updateScreen(); clearError(); } // Backspace function backspace() { if (waitingForNewNumber || isUnaryOperation) return; currentInput = currentInput.slice(0, -1); if (currentInput === '' || currentInput === '-') currentInput = '0'; updateScreen(); } // Делегирование событий keypad.addEventListener('click', (e) => { const btn = e.target.closest('.btn'); if (!btn) return; const op = btn.dataset.op; const num = btn.dataset.num; if (num !== undefined) { appendNumber(num); } else if (op) { if (op === '=') { calculateResult(); } else if (op === 'clear') { clearAll(); } else if (op === 'backspace') { backspace(); } else if (['+', '-', '*', '/'].includes(op)) { setBinaryOp(op); } else if (['sqrt', 'log'].includes(op)) { setUnaryOp(op); } } }); // Инициализация updateScreen(); });