安全计算器应使用<div contenteditable="false">作显示区,统一keydown监听输入,用parseFloat()校验并配合isNaN()拦截无效值,严格处理除零、空表达式等错误,确保缓冲区状态彻底归零。

直接用 <input type="text"> 做显示区,配合 parseFloat() + isNaN() 校验,不依赖框架、不写 eval(),就能跑出安全可用的计算器——关键不是按钮怎么排,而是输入怎么收、错误怎么拦。
显示区域别用 readonly 输入框
iOS Safari 会允许光标聚焦到 <input readonly> 上,用户一碰就清空;语义上它也不是输入,是只读输出。更稳的做法是用一个 <div contenteditable="false">,再加 tabindex="-1" 防止键盘聚焦。
- 设置
textContent更新内容,避免innerHTML引入 XSS 风险 - CSS 加上
user-select: none和pointer-events: none进一步防误触 - 不要用
<input type="number">:它会拦截-和.,导致负数、小数无法输入
数字和运算符统一走 keydown 监听
写 16 个 onclick 函数太重复,也覆盖不了键盘输入。所有输入(数字、+/-/*//、Enter、Backspace)都由一个 input 元素的 keydown 事件捕获。
- 用
switch(event.key)匹配,注意 Mac 小键盘可能发"="而非"Enter",需额外判断event.key === "Enter" || event.key === "=" - 按钮点击时调用同一处理函数,比如
button.addEventListener("click", () => handleInput("5")) - 连续输入两个运算符(如
2++3)要截断,只保留最后一个,否则后续解析会错乱
parseFloat() 比 Number() 更适合表单场景
用户输 " 12.5 "、"12.5.6" 或 "abc12" 时,两者行为差异明显:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
-
parseFloat(" 12.5 ") → 12.5(自动去首尾空格) -
parseFloat("12.5.6") → 12.5(停在第一个非法字符,宽容) -
Number("12.5.6") → NaN(整个字符串不合法就失败)
但宽容不等于放行——必须紧跟 isNaN(result) 检查,无效时清缓冲区并提示,不能让 NaN 流入计算逻辑。
除零、空表达式、非法字符必须显式拦截
浏览器不会帮你报错:1 / 0 得 Infinity,"" / 2 得 0,这些都会继续参与后续运算,最终结果不可信。
- 每次执行
=前,先检查当前表达式是否为空或只含运算符 - 计算后立即用
isFinite(result)判断是否为有效有限数,否则重置显示为"Error"并清空缓冲区 - 过滤掉所有非许可字符(只留
0-9、.、+-*/、=),其他一律忽略或preventDefault()
最易被忽略的是缓冲区状态管理:一次除零后没清空操作栈,下次输入数字还会接着算——错误状态必须彻底归零,而不是只改显示。


















