Files
simple-calculator-web-20260…/script.js
T

191 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ===== 计算器状态 =====
let currentInput = '0'; // 当前输入的数字字符串
let previousValue = null; // 上一个操作数
let currentOperator = null; // 当前运算符
let shouldResetInput = false; // 下次输入是否覆盖当前值
// ===== DOM 元素 =====
const display = document.getElementById('display');
/**
* 更新显示区域
*/
function updateDisplay() {
display.textContent = currentInput;
}
/**
* 输入数字
* @param {string} num
*/
function inputNumber(num) {
if (shouldResetInput) {
currentInput = num;
shouldResetInput = false;
} else {
// 避免出现多个前导 0
currentInput = currentInput === '0' ? num : currentInput + num;
}
updateDisplay();
}
/**
* 输入小数点
*/
function inputDecimal() {
if (shouldResetInput) {
currentInput = '0.';
shouldResetInput = false;
} else if (!currentInput.includes('.')) {
currentInput += '.';
}
updateDisplay();
}
/**
* 执行计算
* @param {number} a
* @param {number} b
* @param {string} op
* @returns {number}
*/
function calculate(a, b, op) {
switch (op) {
case '+': return a + b;
case '-': return a - b;
case '×': return a * b;
case '÷':
if (b === 0) return NaN; // 除零处理
return a / b;
default: return b;
}
}
/**
* 选择运算符
* @param {string} op
*/
function chooseOperator(op) {
const inputValue = parseFloat(currentInput);
// 连续按运算符时,先计算前一步
if (previousValue !== null && currentOperator && !shouldResetInput) {
const result = calculate(previousValue, inputValue, currentOperator);
if (isNaN(result)) {
currentInput = '错误';
previousValue = null;
currentOperator = null;
shouldResetInput = true;
updateDisplay();
return;
}
previousValue = result;
currentInput = formatNumber(result);
} else {
previousValue = inputValue;
}
currentOperator = op;
shouldResetInput = true;
updateDisplay();
}
/**
* 按等号计算结果
*/
function pressEquals() {
if (previousValue === null || currentOperator === null) return;
const inputValue = parseFloat(currentInput);
const result = calculate(previousValue, inputValue, currentOperator);
if (isNaN(result)) {
currentInput = '错误';
} else {
currentInput = formatNumber(result);
}
previousValue = null;
currentOperator = null;
shouldResetInput = true;
updateDisplay();
}
/**
* 清除所有状态
*/
function clearAll() {
currentInput = '0';
previousValue = null;
currentOperator = null;
shouldResetInput = false;
updateDisplay();
}
/**
* 格式化数字,避免过长的小数
* @param {number} num
* @returns {string}
*/
function formatNumber(num) {
if (!isFinite(num)) return '错误';
// 保留最多 10 位有效数字,去掉多余的 0
return parseFloat(num.toPrecision(12)).toString();
}
// ===== 事件绑定 =====
document.querySelector('.keys').addEventListener('click', (e) => {
const btn = e.target.closest('button');
if (!btn) return;
const action = btn.dataset.action;
switch (action) {
case 'number':
inputNumber(btn.dataset.value);
break;
case 'decimal':
inputDecimal();
break;
case 'operator':
chooseOperator(btn.dataset.op);
break;
case 'equals':
pressEquals();
break;
case 'clear':
clearAll();
break;
}
});
// ===== 键盘支持 =====
document.addEventListener('keydown', (e) => {
const key = e.key;
if (/^[0-9]$/.test(key)) {
inputNumber(key);
} else if (key === '.') {
inputDecimal();
} else if (key === '+' || key === '-' || key === '*' || key === '/') {
const map = { '*': '×', '/': '÷', '+': '+', '-': '-' };
chooseOperator(map[key]);
} else if (key === 'Enter' || key === '=') {
e.preventDefault();
pressEquals();
} else if (key === 'Escape' || key.toLowerCase() === 'c') {
clearAll();
} else if (key === 'Backspace') {
// 退格删除
if (currentInput.length > 1 && currentInput !== '错误') {
currentInput = currentInput.slice(0, -1);
} else {
currentInput = '0';
}
updateDisplay();
}
});
// ===== 初始化 =====
updateDisplay();