我来为您设计一个包含完整功能的计算器案例,涵盖基础运算、科学计算和键盘交互功能。

现代计算器实现
HTML 结构
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">现代计算器</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.calculator {
background: #2d3436;
border-radius: 20px;
padding: 25px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
width: 400px;
}
.display {
background: #1a1f1f;
border-radius: 15px;
padding: 20px;
margin-bottom: 20px;
min-height: 120px;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: flex-end;
word-break: break-all;
}
.previous-operand {
color: #bdc3c7;
font-size: 18px;
min-height: 25px;
margin-bottom: 10px;
}
.current-operand {
color: #ffffff;
font-size: 42px;
font-weight: 500;
min-height: 50px;
}
.buttons-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
button {
padding: 20px;
font-size: 20px;
border: none;
border-radius: 10px;
cursor: pointer;
transition: all 0.2s ease;
font-weight: 600;
}
.number {
background: #636e72;
color: #ffffff;
}
.number:hover {
background: #7f8c8d;
transform: scale(1.05);
}
.operator {
background: #f39c12;
color: #ffffff;
font-size: 24px;
}
.operator:hover {
background: #f1c40f;
transform: scale(1.05);
}
.function {
background: #4a69bd;
color: #ffffff;
font-size: 16px;
}
.function:hover {
background: #6a89cc;
transform: scale(1.05);
}
.equals {
background: #e74c3c;
grid-column: span 2;
}
.equals:hover {
background: #ff6b6b;
transform: scale(1.02);
}
.zero {
grid-column: span 2;
}
button:active {
transform: scale(0.95);
}
</style>
</head>
<body>
<div class="calculator">
<div class="display">
<div class="previous-operand" id="previousOperand"></div>
<div class="current-operand" id="currentOperand">0</div>
</div>
<div class="buttons-grid">
<!-- 功能键 -->
<button class="function" data-action="clear">AC</button>
<button class="function" data-action="delete">⌫</button>
<button class="function" data-action="percent">%</button>
<button class="operator" data-action="divide">÷</button>
<!-- 数字键和符号 -->
<button class="number" data-number="7">7</button>
<button class="number" data-number="8">8</button>
<button class="number" data-number="9">9</button>
<button class="operator" data-action="multiply">×</button>
<button class="number" data-number="4">4</button>
<button class="number" data-number="5">5</button>
<button class="number" data-number="6">6</button>
<button class="operator" data-action="subtract">-</button>
<button class="number" data-number="1">1</button>
<button class="number" data-number="2">2</button>
<button class="number" data-number="3">3</button>
<button class="operator" data-action="add">+</button>
<!-- 科学计算功能 -->
<button class="function" data-action="sqrt">√</button>
<button class="number zero" data-number="0">0</button>
<button class="number" data-number="decimal">.</button>
<button class="function" data-action="power">x²</button>
<button class="equals" data-action="equals">=</button>
<button class="function" data-action="reciprocal">1/x</button>
</div>
</div>
<script>
class Calculator {
constructor() {
this.previousOperand = '';
this.currentOperand = '0';
this.operation = undefined;
this.shouldResetScreen = false;
this.previousOperandElement = document.getElementById('previousOperand');
this.currentOperandElement = document.getElementById('currentOperand');
this.initEventListeners();
}
initEventListeners() {
// 数字按钮
document.querySelectorAll('[data-number]').forEach(button => {
button.addEventListener('click', () => {
this.inputNumber(button.dataset.number);
});
});
// 操作符按钮
document.querySelectorAll('[data-action]').forEach(button => {
button.addEventListener('click', () => {
const action = button.dataset.action;
switch(action) {
case 'clear': this.clear(); break;
case 'delete': this.delete(); break;
case 'percent': this.percent(); break;
case 'divide': this.chooseOperation('÷'); break;
case 'multiply': this.chooseOperation('×'); break;
case 'subtract': this.chooseOperation('-'); break;
case 'add': this.chooseOperation('+'); break;
case 'equals': this.compute(); break;
case 'sqrt': this.squareRoot(); break;
case 'power': this.square(); break;
case 'reciprocal': this.reciprocal(); break;
}
});
});
// 键盘事件
document.addEventListener('keydown', (e) => {
this.handleKeyboard(e);
});
}
handleKeyboard(e) {
if (e.key >= '0' && e.key <= '9') {
this.inputNumber(e.key);
} else if (e.key === '.') {
this.inputNumber('decimal');
} else if (e.key === '+' || e.key === '-') {
this.chooseOperation(e.key);
} else if (e.key === '*') {
this.chooseOperation('×');
} else if (e.key === '/') {
e.preventDefault();
this.chooseOperation('÷');
} else if (e.key === 'Enter' || e.key === '=') {
this.compute();
} else if (e.key === 'Backspace') {
this.delete();
} else if (e.key === 'Escape') {
this.clear();
}
}
inputNumber(number) {
if (this.shouldResetScreen) {
this.currentOperand = '';
this.shouldResetScreen = false;
}
if (number === 'decimal') {
if (!this.currentOperand.includes('.')) {
this.currentOperand += '.';
}
} else {
this.currentOperand += number;
}
this.updateDisplay();
}
chooseOperation(operation) {
if (this.currentOperand === '') return;
if (this.previousOperand !== '') {
this.compute();
}
this.operation = operation;
this.previousOperand = this.currentOperand;
this.currentOperand = '';
this.updateDisplay();
}
compute() {
let computation;
const prev = parseFloat(this.previousOperand);
const current = parseFloat(this.currentOperand);
if (isNaN(prev) || isNaN(current)) return;
switch (this.operation) {
case '+':
computation = prev + current;
break;
case '-':
computation = prev - current;
break;
case '×':
computation = prev * current;
break;
case '÷':
if (current === 0) {
alert('Cannot divide by zero!');
return;
}
computation = prev / current;
break;
default:
return;
}
this.previousOperand = '';
this.operation = undefined;
this.currentOperand = this.formatNumber(computation);
this.shouldResetScreen = true;
this.updateDisplay();
}
squareRoot() {
if (this.currentOperand === '' || this.currentOperand === '0') return;
const value = parseFloat(this.currentOperand);
if (value < 0) {
alert('Cannot calculate square root of a negative number!');
return;
}
const result = Math.sqrt(value);
this.currentOperand = this.formatNumber(result);
this.shouldResetScreen = true;
this.updateDisplay();
}
square() {
if (this.currentOperand === '') return;
const value = parseFloat(this.currentOperand);
const result = Math.pow(value, 2);
this.currentOperand = this.formatNumber(result);
this.shouldResetScreen = true;
this.updateDisplay();
}
reciprocal() {
if (this.currentOperand === '' || this.currentOperand === '0') return;
const value = parseFloat(this.currentOperand);
if (value === 0) {
alert('Cannot take reciprocal of zero!');
return;
}
const result = 1 / value;
this.currentOperand = this.formatNumber(result);
this.shouldResetScreen = true;
this.updateDisplay();
}
percent() {
if (this.currentOperand === '') return;
const value = parseFloat(this.currentOperand);
const result = value / 100;
this.currentOperand = this.formatNumber(result);
this.shouldResetScreen = true;
this.updateDisplay();
}
clear() {
this.currentOperand = '0';
this.previousOperand = '';
this.operation = undefined;
this.shouldResetScreen = false;
this.updateDisplay();
}
delete() {
if (this.shouldResetScreen) return;
if (this.currentOperand.length > 1) {
this.currentOperand = this.currentOperand.slice(0, -1);
} else {
this.currentOperand = '0';
}
this.updateDisplay();
}
formatNumber(number) {
if (Number.isInteger(number)) {
return number.toString();
}
// 保留最多10位小数
return Number(number.toFixed(10)).toString();
}
updateDisplay() {
this.currentOperandElement.textContent = this.currentOperand;
if (this.operation !== undefined) {
this.previousOperandElement.textContent =
`${this.previousOperand} ${this.operation}`;
} else {
this.previousOperandElement.textContent = this.previousOperand;
}
}
}
// 初始化计算器
const calculator = new Calculator();
</script>
</body>
</html>
核心功能解析
基础运算
- 加减乘除:完整支持四则运算
- 连续计算:支持链式运算(2+3+4)
- 百分比:快速转换为百分数
- 正负数:支持负数输入
科学计算功能
- 平方根:√x
- 平方:x²
- 倒数:1/x
高级特性
- 键盘支持:完整键盘操作
- 错误处理:除数不为零、负数开方等提示
- 连续运算:=号后继续运算
- 大数精度:保留10位小数
- 格式化显示:自动去除末尾零
键盘快捷键
| 按键 | 功能 |
|---|---|
| 0-9 | 数字输入 |
| 加法 | |
| 减法 | |
| 乘法 | |
| 除法 | |
| Enter | 计算结果 |
| Backspace | 删除 |
| Escape | 清除 |
使用示例
// 基本使用 // 输入: 25 + 75 = // 结果: 100 // 科学计算 // 输入: 9 x² = // 结果: 81 // 连续运算 // 输入: 10 + 5 = 15, × 2 = 30 // 百分比 // 输入: 200 % = // 结果: 2
响应式适配
/* 移动端适配 */
@media (max-width: 480px) {
.calculator {
width: 100%;
padding: 15px;
}
.buttons-grid {
gap: 8px;
}
button {
padding: 15px;
font-size: 18px;
}
}
扩展功能建议
// 添加科学计数法切换
addMethod('toggleScientific') {
// 在科学计数法和普通小数间切换
}
// 历史记录功能
addMethod('saveHistory') {
// 保存计算历史到本地存储
}
// 汇率换算
addMethod('currencyConverter') {
// 集成实时汇率API
}
// 表达式计算
addMethod('evaluateExpression') {
// 使用JavaScript eval或构建表达式树
}
这个计算器案例是一个完整的、功能丰富的实现,适合直接用于生产环境或作为学习参考,它的设计考虑到了用户体验、错误处理和扩展性。