From 824623f7ee018e033fc82b4e2c2abbfb42a5fdb0 Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 28 Sep 2026 20:03:44 +0800 Subject: [PATCH] =?UTF-8?q?AI=20=E7=94=9F=E6=88=90:=20=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=AE=80=E6=B4=81=E7=BE=8E=E8=A7=82=E7=9A=84=E7=BD=91=E9=A1=B5?= =?UTF-8?q?=E8=AE=A1=E7=AE=97=E5=99=A8=EF=BC=8C=E6=94=AF=E6=8C=81=E5=8A=A0?= =?UTF-8?q?=E3=80=81=E5=87=8F=E3=80=81=E4=B9=98=E3=80=81=E9=99=A4=E5=92=8C?= =?UTF-8?q?=E6=B8=85=E9=99=A4=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=BA=AF=20HTML/CSS/JavaScript=20=E5=AE=9E=E7=8E=B0=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 37 +++++++++++ index.html | 42 ++++++++++++ script.js | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 132 +++++++++++++++++++++++++++++++++++++ 4 files changed, 401 insertions(+) create mode 100644 README.md create mode 100644 index.html create mode 100644 script.js create mode 100644 style.css diff --git a/README.md b/README.md new file mode 100644 index 0000000..3dc2a76 --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# Simple Calculator Web + +一个简洁美观的网页计算器,支持加、减、乘、除和清除功能。 + +## 功能 + +- 数字 0-9 输入 +- 小数点输入 +- 加法(+)、减法(-)、乘法(×)、除法(÷) +- 等号(=)计算结果 +- 清除(C)重置计算器 + +## 目录结构 + +``` +simple-calculator-web/ +├── index.html # 主页面 +├── style.css # 样式文件 +├── script.js # 计算逻辑 +└── README.md # 说明文档 +``` + +## 使用方法 + +1. 下载或克隆本项目到本地。 +2. 直接用浏览器打开 `index.html` 即可使用。 +3. 无需安装任何依赖。 + +## 技术栈 + +- HTML5 +- CSS3(Flexbox + Grid 布局) +- 原生 JavaScript(ES6) + +## 预览 + +界面采用深色主题,按钮带有悬停和点击反馈效果,操作直观。 diff --git a/index.html b/index.html new file mode 100644 index 0000000..efc9924 --- /dev/null +++ b/index.html @@ -0,0 +1,42 @@ + + + + + + 简易计算器 + + + +
+ +
0
+ + +
+ + + + + + + + + + + + + + + + + + + + + +
+
+ + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..1f7763b --- /dev/null +++ b/script.js @@ -0,0 +1,190 @@ +// ===== 计算器状态 ===== +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(); diff --git a/style.css b/style.css new file mode 100644 index 0000000..870ce86 --- /dev/null +++ b/style.css @@ -0,0 +1,132 @@ +/* ===== 全局重置 ===== */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; +} + +body { + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; + background: linear-gradient(135deg, #1e1e2f 0%, #2d2d44 100%); + padding: 20px; +} + +/* ===== 计算器容器 ===== */ +.calculator { + width: 100%; + max-width: 360px; + background: #2a2a3d; + border-radius: 20px; + padding: 24px; + box-shadow: 0 20px 50px rgba(0, 0, 0, 0.45), + inset 0 1px 0 rgba(255, 255, 255, 0.05); +} + +/* ===== 显示区域 ===== */ +.display { + background: #1b1b2a; + color: #f5f5f5; + font-size: 2.4rem; + font-weight: 300; + text-align: right; + padding: 20px 18px; + border-radius: 12px; + margin-bottom: 20px; + min-height: 80px; + word-wrap: break-word; + word-break: break-all; + overflow: hidden; + box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.5); + letter-spacing: 1px; +} + +/* ===== 按键网格 ===== */ +.keys { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 12px; +} + +/* ===== 按键基础样式 ===== */ +.key { + border: none; + outline: none; + cursor: pointer; + font-size: 1.4rem; + font-weight: 500; + color: #eaeaea; + background: #3a3a52; + border-radius: 12px; + padding: 18px 0; + transition: transform 0.08s ease, background 0.2s ease, box-shadow 0.2s ease; + user-select: none; + box-shadow: 0 4px 0 #26263a; +} + +.key:hover { + background: #45456a; +} + +.key:active { + transform: translateY(2px); + box-shadow: 0 2px 0 #26263a; +} + +/* ===== 运算符按钮 ===== */ +.key-op { + background: #4a4a78; + color: #ffd166; + font-weight: 600; + box-shadow: 0 4px 0 #2e2e4d; +} + +.key-op:hover { + background: #5a5a92; +} + +/* ===== 清除按钮 ===== */ +.key-clear { + background: #e63946; + color: #fff; + font-weight: 600; + box-shadow: 0 4px 0 #a8232e; +} + +.key-clear:hover { + background: #ff4d5a; +} + +/* ===== 等号按钮(跨两行) ===== */ +.key-equals { + grid-row: span 2; + background: linear-gradient(180deg, #06d6a0, #04b184); + color: #fff; + font-weight: 700; + font-size: 1.6rem; + box-shadow: 0 4px 0 #028a66; +} + +.key-equals:hover { + background: linear-gradient(180deg, #0be0aa, #05c492); +} + +/* ===== 0 按钮跨两列 ===== */ +.key-zero { + grid-column: span 2; +} + +/* ===== 响应式 ===== */ +@media (max-width: 400px) { + .display { + font-size: 1.9rem; + padding: 16px 14px; + } + .key { + font-size: 1.2rem; + padding: 15px 0; + } +}