124 lines
4.5 KiB
HTML
124 lines
4.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>计算器组件</title>
|
|
<link rel="stylesheet" href="../../assets/css/widgets.css">
|
|
</head>
|
|
<body>
|
|
<div class="widget glass">
|
|
<h3 class="widget-title">计算器</h3>
|
|
<div class="calculator-display" id="calc-display">0</div>
|
|
<div class="calculator-buttons">
|
|
<button class="calc-btn" data-value="C">C</button>
|
|
<button class="calc-btn" data-value="+">+</button>
|
|
<button class="calc-btn" data-value="-">-</button>
|
|
<button class="calc-btn" data-value="/">/</button>
|
|
<button class="calc-btn" data-value="7">7</button>
|
|
<button class="calc-btn" data-value="8">8</button>
|
|
<button class="calc-btn" data-value="9">9</button>
|
|
<button class="calc-btn" data-value="*">*</button>
|
|
<button class="calc-btn" data-value="4">4</button>
|
|
<button class="calc-btn" data-value="5">5</button>
|
|
<button class="calc-btn" data-value="6">6</button>
|
|
<button class="calc-btn" data-value=".">.</button>
|
|
<button class="calc-btn" data-value="1">1</button>
|
|
<button class="calc-btn" data-value="2">2</button>
|
|
<button class="calc-btn" data-value="3">3</button>
|
|
<button class="calc-btn calc-equals" data-value="=">=</button>
|
|
<button class="calc-btn" data-value="0">0</button>
|
|
<button class="calc-btn" data-value="00">00</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// 计算器功能
|
|
const display = document.getElementById('calc-display');
|
|
let currentValue = '0';
|
|
let previousValue = null;
|
|
let operator = null;
|
|
let resetOnNextInput = false;
|
|
|
|
function updateDisplay() {
|
|
display.textContent = currentValue;
|
|
}
|
|
|
|
function handleNumber(value) {
|
|
if (resetOnNextInput) {
|
|
currentValue = '0';
|
|
resetOnNextInput = false;
|
|
}
|
|
|
|
if (currentValue === '0' && value !== '.') {
|
|
currentValue = value;
|
|
} else if (value === '.' && currentValue.includes('.')) {
|
|
// 不允许重复的小数点
|
|
return;
|
|
} else {
|
|
currentValue += value;
|
|
}
|
|
|
|
updateDisplay();
|
|
}
|
|
|
|
function handleOperator(nextOperator) {
|
|
const inputValue = parseFloat(currentValue);
|
|
|
|
if (operator && resetOnNextInput) {
|
|
operator = nextOperator;
|
|
return;
|
|
}
|
|
|
|
if (previousValue !== null && operator) {
|
|
try {
|
|
// 使用 Function 来安全地计算表达式
|
|
const expression = `${previousValue} ${operator} ${inputValue}`;
|
|
// 简单的安全检查
|
|
if (/^[\d\s\+\-\*\/\.]+$/.test(expression)) {
|
|
const result = new Function('return ' + expression)();
|
|
currentValue = String(result);
|
|
previousValue = result;
|
|
}
|
|
} catch (e) {
|
|
currentValue = 'Error';
|
|
}
|
|
} else {
|
|
previousValue = inputValue;
|
|
}
|
|
|
|
operator = nextOperator;
|
|
resetOnNextInput = true;
|
|
updateDisplay();
|
|
}
|
|
|
|
function handleClear() {
|
|
currentValue = '0';
|
|
previousValue = null;
|
|
operator = null;
|
|
resetOnNextInput = false;
|
|
updateDisplay();
|
|
}
|
|
|
|
// 事件监听
|
|
document.querySelectorAll('.calc-btn').forEach(button => {
|
|
button.addEventListener('click', () => {
|
|
const value = button.getAttribute('data-value');
|
|
|
|
if (value === 'C') {
|
|
handleClear();
|
|
} else if (['+', '-', '*', '/'].includes(value)) {
|
|
handleOperator(value);
|
|
} else if (value === '=') {
|
|
handleOperator('=');
|
|
} else {
|
|
handleNumber(value);
|
|
}
|
|
});
|
|
});
|
|
|
|
// 初始化
|
|
updateDisplay();
|
|
</script>
|
|
</body>
|
|
</html> |