简易计算器应使用 readonly input 或 contenteditable="false" div 作显示区,禁用 eval,采用状态机解析表达式,统一事件监听并处理 0 开头、连续运算符等边界情况。

直接用浏览器就能跑的简易计算器,不需要服务器、不装环境,只要写好 index.html 文件双击打开就行。关键不是“怎么运行”,而是“怎么避免常见逻辑崩坏”——比如连续点 = 崩出 NaN,或者 1 + 2 + 后再按数字直接覆盖而不是追加。
HTML结构要避开 disabled 输入框的交互陷阱
很多人用 <input type="text" disabled> 当显示屏,结果发现 JS 无法聚焦、无法选中文本、复制也受限。这不是 bug,是 disabled 的语义行为。
- 改用
<div contenteditable="false">或更稳妥的<span id="display">——只读但 DOM 可控 - 如果坚持用
input,必须用readonly而非disabled,否则.focus()和样式高亮都会失效 -
readonly下仍能通过 JS 修改.value,且支持 CSS 的:read-only伪类做视觉区分
JavaScript 计算逻辑不能直接 eval() 表达式字符串
新手常写 eval(display.textContent) 来算 "1+2*3",这在本地开发看似可行,但实际有严重风险:用户输入 "alert(1)" 也能执行;Chrome 会报 Refused to evaluate a string as JavaScript(CSP 策略拦截)。
- 真要解析表达式,用分步状态机:记录上一个数字、上一个运算符、是否等待下个数字
- 简单场景下,用
Function('return ' + expr)()比eval略安全(仍不推荐生产环境) - 最稳做法:只允许「数字+单运算符+数字」模式,比如
5 + 3→ 算完后清空,下次从头输;避免累积表达式
按钮事件绑定别全靠 onclick="xxx()" 写死在 HTML 里
内联 onclick 看似快,但调试时看不到调用栈,也不能统一拦截错误,更没法动态增删按钮逻辑。
立即学习“前端免费学习笔记(深入)”;
- 用
document.querySelectorAll('.btn').forEach(btn => btn.addEventListener('click', handler)) - 给每个按钮加
data-action属性,比如data-action="digit"、data-value="7"、data-action="operator"、data-value="*" - 这样所有逻辑收口到一个
handleClick(e)函数里,后续加小数点、正负号、退格都只需改分支,不动 HTML
容易被忽略的边界情况:0 开头、连续运算符、空输入
用户按 0 → 0 → 1,你得阻止变成 001;按 + → + 应覆盖前一个,而不是拼成 ++;按 C 后再按 = 不该报错或卡死。
- 每次更新显示前,用正则清理无效开头:
expr.replace(/^0+(?=\d)/, '') - 连续运算符只保留最后一个,用
expr.replace(/[\+\-\*\/]+$/, lastOp)动态替换 -
=按下时先检查当前表达式是否含数字和运算符,否则跳过计算直接 return



















