一、完整代码:
1、HTML代码
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>JavaScript实现的简单计算器</title>
<!--引入页面样式文件 -->
<link rel="stylesheet" type="text/css" href="css/mr-style.css">
<script language="javascript">
var num=0;
var result=0;
var numshow="0";
var operate=0; //判断输入状态的标志
var calcul=0; //判断计算状态的标志
var quit=0; //防止重复按键的标志
//复原为0
function command(num){
var str=String(document.calculator.numScreen.value); //获得当前显示数据
str=(str!="0") ? ((operate==0) ? str : "") : ""; //如果当前值不是"0",且状态为0,则返回当前值,否则返回空值;
str=str + String(num); //给当前值追加字符
document.calculator.numScreen.value=str; //刷新显示
operate=0; //重置输入状态
quit=0; //重置防止重复按键的标志
}
//验证是否为0
function dzero(){
var str=String(document.calculator.numScreen.value);
str=(str!="0") ? ((operate==0) ? str + "00" : "0") : "0"; //如果当前值不是"0",且状态为0,则返回当str+"00",否则返回"0";
document.calculator.numScreen.value=str;
operate=0;
}
//验证是否有小数点
function dot(){
var str=String(document.calculator.numScreen.value);
str=(str!="0") ? ((operate==0) ? str : "0") : "0"; //如果当前值不是"0",且状态为0,则返回当前值,否则返回"0";
for(i=0; i<=str.length;i++){ //判断是否已经有一个点号
if(str.substr(i,1)==".") return false; //如果有则不再插入
}
str=str + ".";
document.calculator.numScreen.value=str;
operate=0;
}
//退格
function del(){
var str=String(document.calculator.numScreen.value);
str=(str!="0") ? str : "";
str=str.substr(0,str.length-1);
str=(str!="") ? str : "0";
document.calculator.numScreen.value=str;
}
//清除数据
function clearscreen(){
num=0;
result=0;
numshow="0";
document.calculator.numScreen.value="0";
}
//加法
function plus(){
calculate(); //调用计算函数
operate=1; //更改输入状态
calcul=1; //更改计算状态为加
}
//减法
function minus(){
calculate();
operate=1;
calcul=2;
}
//乘法
function times(){
calculate();
operate=1;
calcul=3;
}
//除法
function divide(){
calculate();
operate=1;
calcul=4;
}
//求余
function persent(){
calculate();
operate=1;
calcul=5;
}
//等于
function equal(){
calculate();
operate=1;
num=0;
result=0;
numshow="0";
}
//计算
function calculate(){
numshow=Number(document.calculator.numScreen.value);
if(num!=0 && quit!=1){ //判断前一个运算数是否为零以及防重复按键的状态
switch(calcul){ //判断要输入状态
case 1:result=num+numshow;break; //计算"+"
case 2:result=num-numshow;break; //计算"-"
case 3:result=num*numshow;break;
case 4:if(numshow!=0){result=num/numshow;}else{document.getElementById("note").innerHTML="被除数不能为零!"; setTimeout(clearnote,4000)} break;
case 5:result=num%numshow;break;
}
quit=1; //避免重复按键
}
else{
result=numshow;
}
numshow=String(result);
document.calculator.numScreen.value=numshow;
num=result; //存储当前值
}
//清空提示
function clearnote(){
document.getElementById("note").innerHTML="";
}
</script>
</head>
<body>
<div id="mr-calculator">
<div id="calcu-head"><h6>简单的计算器</h6></div>
<form name="calculator" action="" method="get">
<div id="calcu-screen">
<!--显示窗口,避免键盘输入-->
<input type="text" name="numScreen" class="screen" value="0" onfocus="this.blur();" />
</div>
<div >
<ul> <!--显示计算按钮-->
<li onclick="command(7)">7</li>
<li onclick="command(8)">8</li>
<li onclick="command(9)">9</li>
<li class="tool" onclick="del()">←</li>
<li class="tool" onclick="clearscreen()">C</li>
<li onclick="command(4)">4</li>
<li onclick="command(5)">5</li>
<li onclick="command(6)">6</li>
<li class="tool" onclick="times()">×</li>
<li class="tool" onclick="divide()">÷</li>
<li onclick="command(1)">1</li>
<li onclick="command(2)">2</li>
<li onclick="command(3)">3</li>
<li class="tool" onclick="plus()">+</li>
<li class="tool" onclick="minus()">-</li>
<li onclick="command(0)">0</li>
<li onclick="dzero()">00</li>
<li onclick="dot()">.</li>
<li class="tool" onclick="persent()">%</li>
<li class="tool" onclick="equal()">=</li>
</ul>
</div>
</form>
</div>
</body>
</html>2、CSS代码
body {
font-size:12px;
font-family:Arial, Georgia, "Times New Roman", Times, serif;
color:#555;
text-align:center;
background-color:#e2e2e2;
}
h6{
margin:0;
font-size:16px;
}
#mr-calculator {
width:480px;
height:auto;
overflow:hidden;
margin:10px auto;
border:#fff 1px solid;
padding-bottom:10px;
background-color:#f2f2f2;
}
#mr-calculator div {
clear:both;
}
#mr-calculator ul{
padding:0;
margin:5px 35px;
height:auto;
overflow:hidden
}
#mr-calculator li{
list-style:none;
float:left;
width:70px;
height:32px;
margin:5px;
display:inline;
line-height:32px;
font-size:14px;
background-color:#eaeaea;
}
#mr-calculator li.tool{
background-color:#e2e2e2;
}
#mr-calculator li:hover{
background-color:#f9f9f9;
cursor:pointer;
}
#mr-calculator li:active{
background-color:#fc0;
cursor:pointer;
}
#mr-calculator li.tool:active{
background-color:#d8e8ff;
cursor:pointer;
}
#calcu-head {
text-align:center;
padding:10px 15px 5px;
}
span.imyeah {
float:right;
color:#ccc;
}
span.imyeah a{
color:#ccc;
}
.screen{
width:400px;
height:24px;
line-height:24px;
padding:4px;
border:#e6e6e6 1px solid;
border-bottom:#f2f2f2 1px solid;
border-right:#f2f2f2 1px solid;
margin:10px auto;
direction:ltr;
text-align:right;
font-size:16px;
color:#999;
}
#calcu-foot{
text-align:left;
padding:10px 15px 5px;
height:auto;
overflow:hidden;
}
span#note{
float:left;
width:210px;
height:auto;
overflow:hidden;
color:red;
}
span.welcome{
clear:both;
color:#999;
}
span.welcome a{
float:right;
color:#999;
}3、运行图:

二、HTML代码分析
第一部分:变量声明与初始化 (第8-13行)
var num=0; var result=0; var numshow="0"; var operate=0; //判断输入状态的标志 var calcul=0; //判断计算状态的标志 var quit=0; //防止重复按键的标志
第8行
var num=0;: 声明变量num并初始化为0。这个变量是计算器的核心存储器,用于保存第一个运算数或上一次计算的结果。例如,在计算3 + 4时,按下+后,3会被存入num。第9行
var result=0;: 声明变量result并初始化为0。这个变量用于临时存储计算结果。当执行3 + 4时,7会先被计算出来并存入result,然后再显示并转存到num。第10行
var numshow="0";: 声明变量numshow并初始化为字符串"0"。这个变量用于存储当前屏幕上显示内容的字符串形式,方便进行字符串操作(如追加、退格)。第11行
var operate=0;: 声明变量operate并初始化为0。这是一个输入状态标志。0表示可以继续在当前数字后追加输入;1表示刚刚按下了运算符(如+),下一个数字输入应该清空屏幕重新开始。第12行
var calcul=0;: 声明变量calcul并初始化为0。这是一个计算状态标志,用于记录用户按下了哪个运算符。其值对应关系为:1->加(+),2->减(-),3->乘(×),4->除(÷),5->求余(%)。第13行
var quit=0;: 声明变量quit并初始化为0。这是一个防重复按键标志。当连续按下两个运算符时(如+后马上按×),它确保只执行一次计算,防止逻辑错误。
第二部分:数字输入函数 command(num) (第16-25行)
function command(num){
var str=String(document.calculator.numScreen.value); //获得当前显示数据
str=(str!="0") ? ((operate==0) ? str : "") : ""; //如果当前值不是"0",且状态为0,则返回当前值,否则返回空值;
str=str + String(num); //给当前值追加字符
document.calculator.numScreen.value=str; //刷新显示
operate=0; //重置输入状态
quit=0; //重置防止重复按键的标志
}这个函数处理数字按钮(0-9)的点击事件。
第16行
function command(num){: 定义函数command,它接收一个参数num,即被点击的数字。第17行
var str=String(...);: 获取计算器显示屏(name="numScreen"的输入框)的当前值,并将其转换为字符串类型,赋值给局部变量str。这是为了后续进行字符串拼接。第18行
str=(str!="0") ? ((operate==0) ? str : "") : "";: 这是决定是否清屏的核心逻辑,一个嵌套的三元运算符。如果
operate==0(没有刚按过运算符),则结果为str(保留当前显示)。如果
operate==1(刚按过运算符),则结果为""(清空当前显示,准备输入新数字)。如果
str不是"0",则进入内层判断。如果
str就是"0",则整个表达式结果为""(空字符串)。这意味着如果屏幕上只有一个"0",按数字键时会先清掉这个"0"。最外层:
(str!="0") ? ... : ""。判断当前显示str是否不等于"0"。内层:
((operate==0) ? str : "")。判断operate标志是否为0。第19行
str=str + String(num);: 将传入的数字参数num也转为字符串,并追加到处理后的str末尾。第20行
document.calculator.numScreen.value=str;: 将新的字符串str设置回显示屏,完成屏幕刷新。第21行
operate=0;: 将输入状态标志operate重置为0。因为已经输入了数字,后续可以继续在这个数字后追加。第22行
quit=0;: 将防重复按键标志quit重置为0,为下一次可能的运算符计算做准备。
第三部分:特殊输入函数
1. 双零函数 dzero() (第25-31行)
function dzero(){ var str=String(document.calculator.numScreen.value);
str=(str!="0") ? ((operate==0) ? str + "00" : "0") : "0"; //如果当前值不是"0",且状态为0,则返回当str+"00",否则返回"0";
document.calculator.numScreen.value=str;
operate=0;
}逻辑与
command类似,但追加的是"00"。第27行:如果当前不是
"0"且operate==0,则追加"00";否则(刚按过运算符或当前就是"0"),显示"0"。
2. 小数点函数 dot() (第33-42行)
function dot(){ var str=String(document.calculator.numScreen.value);
str=(str!="0") ? ((operate==0) ? str : "0") : "0"; //如果当前值不是"0",且状态为0,则返回当前值,否则返回"0";
for(i=0; i<=str.length;i++){ //判断是否已经有一个点号
if(str.substr(i,1)==".") return false; //如果有则不再插入
}
str=str + "."; document.calculator.numScreen.value=str;
operate=0;
}第35行: 处理显示逻辑,确保在刚按完运算符后输入小数点,显示的是
"0."而不是"."。第36-39行: 关键! 用一个
for循环遍历当前字符串str的每一个字符 (str.substr(i,1)获取第i个字符)。如果发现任何一个字符是小数点
".",则执行return false;直接结束函数,不再添加小数点。这确保了一个数字中只能有一个小数点。第40行: 如果没有找到小数点,则在字符串末尾追加小数点
"."。
3. 退格函数 del() (第44-51行)
function del(){ var str=String(document.calculator.numScreen.value);
str=(str!="0") ? str : "";
str=str.substr(0,str.length-1);
str=(str!="") ? str : "0"; document.calculator.numScreen.value=str;
}第46行: 如果当前显示不是
"0",则str保持原值;如果是"0",则设为空字符串""(因为"0"不需要退格)。第47行: 使用
str.substr(0, str.length-1)方法。这个方法从索引0开始,截取长度为原长度-1的子字符串,效果就是去掉最后一个字符。第48行: 如果退格后字符串不为空
"",则保持;如果为空,则设回"0",避免屏幕空白。
4. 清零函数 clearscreen() (第53-58行)
function clearscreen(){
num=0;
result=0;
numshow="0"; document.calculator.numScreen.value="0";
}这个函数最简单,它将所有核心变量重置为初始状态,并将屏幕显示清零。注意它没有重置
operate,calcul,quit,这是一个小特点(或小缺陷),但通常不影响使用,因为按下C后用户的下一个操作大概率是输入数字。
第四部分:运算符函数
这些函数结构类似,以加法 plus() 为例 (第60-64行):
function plus(){ calculate(); //调用计算函数
operate=1; //更改输入状态
calcul=1; //更改计算状态为加
}第61行
calculate();: 关键调用! 按下运算符后,首先调用calculate()函数。这个函数会根据之前存储的状态,执行上一次的运算。例如,输入3 + 4后按下×,在times()函数里,calculate()会先算出3+4=7。第62行
operate=1;: 将输入状态标志设为1。这告诉后续的command、dot等函数:“我刚按了运算符,下一个输入的数字是新操作数的开始,请清屏。”第63行
calcul=1;: 将计算状态标志设为1,代表“加法”。这个值会被calculate()函数在下一次运算时使用。
减法(minus)、乘法(times)、除法(divide)、求余(persent)函数逻辑完全相同,只是 calcul 的值分别设为 2, 3, 4, 5。
第五部分:等号函数 equal() (第78-84行)
function equal(){ calculate();
operate=1;
num=0;
result=0;
numshow="0";
}第79行
calculate();: 调用计算函数,执行最后一次运算。第80行
operate=1;: 和运算符一样,设置输入状态,等待新输入。第81-83行: 与运算符函数的唯一区别! 它将
num,result,numshow全部重置。这意味着按下等号后,计算链条被完全切断。如果再按运算符,会以当前显示结果为起点开始新的计算。
第六部分:核心计算函数 calculate() (第86-107行)
function calculate(){
numshow=Number(document.calculator.numScreen.value); if(num!=0 && quit!=1){ //判断前一个运算数是否为零以及防重复按键的状态
switch(calcul){ //判断要输入状态
case 1:result=num+numshow;break; //计算"+"
case 2:result=num-numshow;break; //计算"-"
case 3:result=num*numshow;break; case 4:if(numshow!=0){result=num/numshow;}else{document.getElementById("note").innerHTML="被除数不能为零!"; setTimeout(clearnote,4000)} break; case 5:result=num%numshow;break;
}
quit=1; //避免重复按键
} else{
result=numshow;
}
numshow=String(result); document.calculator.numScreen.value=numshow;
num=result; //存储当前值
}这是整个计算器的大脑。
第87行
numshow=Number(...);: 获取屏幕显示值并转为数字类型,存入变量numshow。第88行
if(num!=0 && quit!=1){: 执行计算的判断条件。num!=0: 判断是否已经存在一个存储的操作数(num)。如果是第一次按运算符,num为0,条件为假,跳转到else块。quit!=1: 防重复按键。一旦执行了计算,quit会被设为1。如果用户紧接着又按了一个运算符,由于quit==1,条件为假,不会用同一个numshow重复计算。第89-97行
switch(calcul){...}: 如果条件为真,进入switch语句,根据之前设置的calcul值(1,2,3,4,5)执行相应的算术运算,结果存入result。特别注意第92行除法: 增加了除零检查。如果除数
numshow为0,则不计算,而是在页面某个id="note"的元素中显示错误信息,并设置一个4秒后清除该信息的定时器 (setTimeout)。第98行
quit=1;: 计算完成后,立即将quit设为1,防止下一次按键误触发计算。第100-102行
else{ result=numshow; }: 如果if条件不成立(即第一次按运算符或防重复状态激活),则不进行运算,直接将屏幕值numshow赋给result。这实现了第一个数字的“存储”。第103行
numshow=String(result);: 将计算结果result转回字符串,更新numshow变量。第104行
document.calculator.numScreen.value=numshow;: 将结果显示在屏幕上。第105行
num=result;: 灵魂语句! 将本次的计算结果result存入num。这样,当用户按下下一个运算符时,num就变成了下一次运算的“第一个数”,实现了连续计算。
第七部分:HTML界面部分 (第115-150行)
这部分构建了计算器的按钮和显示框。
第121行
<input type="text" name="numScreen" ... onfocus="this.blur();" />:name="numScreen": 为输入框命名,JavaScript 代码通过document.calculator.numScreen来访问它。onfocus="this.blur();": 重要属性。当输入框获得焦点(被点击)时,立即执行this.blur()使其失去焦点。这防止了手机或电脑的虚拟键盘弹出,强制用户只能使用屏幕上的按钮进行操作。第124-149行
<ul>和<li>: 用列表项 (<li>) 作为计算器的每一个按钮。每个
<li>都通过onclick属性绑定了对应的 JavaScript 函数。例如onclick="command(7)"表示点击这个按钮会调用command(7)函数。数字按钮绑定
command(数字)。运算符按钮绑定
plus(),minus()等。功能键绑定
del(),clearscreen(),equal()等。
三、CSS配套设置
(一)整体设计理念与基础设置
这部分代码设定了整个页面的基调。
body样式 (第1-7行):字体与排版: 使用
Arial等通用无衬线字体族,字号为12px,颜色为中性灰 (#555),并设置text-align:center使整个页面内容居中。这奠定了清晰易读、中性的视觉基础。背景: 将整个页面背景设置为浅灰色 (
#e2e2e2)。这有两个作用:一是作为计算器容器的衬托,二是形成视觉上的“画布”或“底板”,让计算器主体更突出。
h6样式 (第8-11行):将
h6标题的默认外边距 (margin) 清零,并设置较大的16px字号。这通常用于计算器顶部的标题区域(如“计算器”字样),使其醒目且布局紧凑。
(二)计算器主体容器 (#mr-calculator) 的设计
这是包裹整个计算器的“盒子”,定义了其基本尺寸和视觉层次。
尺寸与布局 (第13-20行):
设置固定宽度
480px,高度自适应 (auto),并通过margin:10px auto实现水平居中。这是构建一个独立、规整UI组件的标准做法。overflow:hidden可以清除内部浮动元素可能造成的高度塌陷问题。通过
border、padding-bottom和background-color:#f2f2f2,为容器添加了轻微的边框、底部内边距和比页面背景稍亮的背景色。这形成了从深背景(页面) -> 浅背景(容器) -> 更浅背景(内部元素) 的层次感,让计算器看起来像一块略微浮起的面板。内部布局重置 (第21-23行):
#mr-calculator div { clear:both; }是一个重要的布局技巧。它确保容器内所有的div元素都能清除之前的浮动,从而各自从新行开始。这为内部可能的分区(如显示区、按钮区、脚注区)提供了干净的布局起点。
(三)核心交互区域:按钮列表 (ul 与 li) 的设计
这是整个CSS的精髓,直接定义了用户操作的核心——按钮的视觉和交互。
列表容器 (
ul) 样式 (第24-29行):重置了默认的
padding和margin,并通过margin:5px 35px在左右两侧留出较宽的边距,使按钮组在容器内看起来不拥挤。height:auto; overflow:hidden同样是用于处理内部浮动列表项 (li) 的布局,确保ul能正确包裹所有按钮。按钮 (
li) 基础样式 (第30-40行):line-height:32px将行高设置为与高度相同,实现了文字的完美垂直居中。font-size:14px确保按钮文字大小合适。background-color:#eaeaea设置了按钮的默认背景色,比容器背景 (#f2f2f2) 略深,形成微妙的对比,使按钮具有可点击的“凸起”感。去除列表标识:
list-style:none去掉项目符号。创建网格布局: 这是关键。通过
float:left让所有li向左浮动,结合固定的width:70px和height:32px,以及margin:5px,自然而然地形成了一个整齐的按钮网格。display:inline是某些浏览器下的兼容性补充。视觉设计:
工具按钮的特殊类 (第41-43行):
.tool类(可能应用于C、DEL、%等按钮)被赋予了background-color:#e2e2e2。这个颜色与页面背景相同或接近,在视觉上将功能键与数字/运算符键区分开来,暗示它们属于不同的操作类别。交互状态 (第44-55行):
普通按钮按下时,背景色变为亮黄色 (
#fc0),模拟了“被按下”的瞬间反馈。工具按钮 (
.tool:active) 按下时,背景色变为淡蓝色 (#d8e8ff)。这种颜色区分进一步强化了按钮的类型差异,让交互体验更细腻。悬停状态 (
:hover): 当鼠标移动到按钮上时,背景色变为更亮的#f9f9f9,光标变为手形 (cursor:pointer)。这提供了明确的视觉反馈,告诉用户这个元素是可交互的。激活状态 (
:active):
(四)其他组件的细节设计
头部区域 (
#calcu-head) (第57-60行):用于放置标题或Logo,通过
padding控制内部间距,保持内容居中。版权信息 (
span.imyeah) (第61-66行):使用
float:right使其右对齐,颜色为浅灰色 (#ccc),既保留了信息,又使其不喧宾夺主,符合脚注或版权信息的常规设计。显示屏 (
screen类) (第67-80行):通过精心设置的
border颜色(上/左边缘略深,下/右边缘略亮),创造了经典的内凹效果,让屏幕看起来像是嵌入在面板里,增强了立体感和真实感。背景应为白色(未明确设置,可能继承或默认),文字颜色为灰色 (
#999),模仿液晶屏的显示效果。尺寸与布局: 固定宽度 (
400px),居中对齐 (margin:10px auto),文本右对齐 (text-align:right) 并设置方向 (direction:ltr),完美模拟了真实计算器的显示屏。视觉设计:
脚部区域 (
#calcu-foot) 与提示信息 (第81-95行):#calcu-foot区域左对齐,用于容纳提示信息和欢迎语。#note用于显示错误信息(如“被除数不能为零!”),颜色为醒目的红色 (red),并设置为浮动左对齐,与右边的版权信息形成平衡。.welcome类用于次要的欢迎或说明文字,颜色为灰色 (#999),并通过clear:both清除浮动,确保自己在新行显示。
总结:设计逻辑与构思
层次与结构: 通过背景色的深浅变化 (
#e2e2e2->#f2f2f2->#eaeaea),清晰地构建了“页面-计算器面板-按钮”的三层视觉层次,使界面结构一目了然。网格化布局: 利用
float:left配合固定宽高和边距,以最简洁的CSS实现了计算器按钮的网格布局,代码高效且兼容性好。拟物化与扁平化结合:
拟物化: 显示屏的“内凹”边框、按钮按下 (
:active) 时的颜色变化,都模拟了物理设备的交互反馈。扁平化: 整体使用纯色块、无渐变、无复杂阴影,符合现代简洁的UI设计趋势。
清晰的视觉分类: 通过为工具按钮 (
.tool) 设置不同的默认色和激活色,在视觉上将数字键、运算符键和功能键区分开,提升了界面的可读性和易用性。完整的交互反馈闭环: 设计了
:hover(悬停)和:active(按下)两种状态,为用户操作提供了即时、明确的视觉反馈,极大地提升了用户体验。细节考量: 考虑了文字垂直居中、错误信息突出显示、次要信息弱化、布局清除等细节,使得整个计算器看起来精致、专业。
总而言之,这份CSS代码的构思是以用户体验为中心,通过严谨的盒模型控制、精心的颜色选择和完整的交互状态定义,将一个由HTML列表和输入框组成的简单结构,美化成了一个直观、美观、反应灵敏的虚拟计算器界面。
四、计算器制作逻辑分析
代码实现了一个在网页上运行的简单计算器,包含了基本的四则运算、求余、清零、退格等功能。
(一)整体结构与初始化
HTML骨架:代码是一个完整的HTML文件,包含
<head>和<body>。计算器的界面通过HTML元素(如<input>输入框和<li>列表项作为按钮)构建。核心变量初始化(代码开头部分):
var num=0;: 用来存储第一个运算数或上一次的计算结果,是参与运算的“左值”。var result=0;: 用来存储临时的计算结果。var numshow="0";: 用来存储当前屏幕上显示的字符串,初始为"0"。var operate=0;: 输入状态标志。0表示可以开始输入一个新的数字;1表示刚刚按下了运算符(如+),需要清空当前显示以输入下一个数字。var calcul=0;: 计算状态标志。记录当前选择的运算符(1=加,2=减,3=乘,4=除,5=求余)。var quit=0;: 防重复按键标志。防止连续按两次运算符导致计算错误。
(二)数字输入与显示逻辑
这是计算器最基础的功能,由command(num)函数处理。
获取当前显示:
var str=String(document.calculator.numScreen.value);获取屏幕上显示的内容。判断显示重置条件:
如果当前显示不是"0":
如果当前显示就是"0",则
str变为空字符串""(避免在"0"前面追加数字)。且
operate==0(未按运算符),则str保持原值(继续追加数字)。且
operate==1(刚按了运算符),则str变为空字符串""(清空旧数,准备输入新数)。str=(str!="0") ? ((operate==0) ? str : "") : "";这是一个三层判断:追加新数字:
str=str + String(num);将按下的数字键追加到字符串末尾。更新显示与状态:将新的
str显示在屏幕上,并将operate和quit重置为0,表示进入正常的数字输入状态。
举例:屏幕上显示"12",此时按"3"。因为operate=0,str保持"12",追加"3"后变成"123"显示。如果先按了"+"键(operate=1),再按"3",则str先被清空为"",再追加"3",显示为"3"。
(三)特殊输入处理
小数点(
dot()):先按
command函数的逻辑判断是否要清屏。关键:用一个
for循环检查当前字符串是否已包含小数点(.)。如果已包含,函数直接返回(return false),不再添加,确保一个数字最多只有一个小数点。如果没有小数点,则在末尾追加"."。
双零(
dzero()):逻辑类似,但追加的是"00"。主要用于快速输入整百、整千等数字。
退格(
del()):获取当前字符串,如果不是"0",就使用
substr方法截取掉最后一个字符。如果截取后字符串为空,则显示"0"。
清零(
clearscreen()):最简单直接:将所有核心变量(
num,result,numshow,operate,calcul,quit)恢复为初始状态。将屏幕显示重置为"0"。
(四)运算逻辑(核心)
这是代码最精彩的部分,采用了一种“延迟计算”的模式:不是在你按下等号时才计算,而是在你按下下一个运算符时,才计算上一个运算符的表达式。
步骤分解:
第一步:按下运算符(如plus()加号)
立即调用
calculate()函数(这里开始计算上一个操作,如果是第一次按运算符,则只是存储数字)。设置
operate=1,告诉输入逻辑“下一个按键是新数字的开始”。设置
calcul=1(对于plus函数),记录“接下来要执行的运算是加法”。
第二步:calculate()计算函数详解
获取当前显示值:
numshow=Number(...)将屏幕上显示的字符串转为数字。判断是否真正需要计算:
if(num!=0 && quit!=1)这是关键。num!=0:判断是否已有存储的第一个运算数(num)。如果是第一次按运算符,num为0,不进入计算分支,只做存储。quit!=1:防止重复按键。一旦进入计算分支,会设置quit=1,如果紧接着再按其他运算符,就不会重复计算。如果进入计算分支(
if内):根据之前存储的
calcul标志(1,2,3,4,5),使用switch语句,用存储的num(第一个数)和当前的numshow(刚输入的第二个数)进行相应的计算,结果存入result。特别注意除法:增加了除零判断。如果除数为0,则在页面ID为
note的元素(代码中未显示但逻辑存在)显示错误提示,4秒后清除。设置
quit=1,防止本次计算被下一个运算符重复触发。如果不进入计算分支(
else内):说明是第一次按运算符,没有前序运算。直接将当前显示的数字
numshow赋给result。更新显示与存储:
将计算结果
result转为字符串,显示在屏幕上。num=result;这是核心中的核心:将本次的计算结果存储到num中,作为下一次运算的第一个数。这就实现了连续计算(如 3 + 4 + 5)。
第三步:输入下一个数字
由于
operate=1,command函数会清空屏幕,然后输入新数字。
第四步:按下等号(equal())
调用
calculate(),执行最后一次运算。设置
operate=1。关键区别:它将
num,result,numshow全部归零。这意味着等号之后,计算链条被重置。如果再按数字,会从"0"开始;如果再按运算符,会以当前显示结果为起点开始新的计算链。
(五)界面与交互
显示框:
<input type="text" name="numScreen" ... onfocus="this.blur();" />。onfocus="this.blur()"使得点击输入框时自动失去焦点,防止键盘弹出,强制用户使用屏幕按钮操作。按钮:每个
<li>元素都通过onclick事件绑定到对应的函数。数字按钮绑定command(),运算符绑定各自的函数,功能键绑定del(),clearscreen()等。
(六)逻辑总结与流程示例
计算 3 + 4 × 2 = 的流程:
按 3:
command(3)-> 屏幕显示"3"。按 +:
plus()->calculate():因num=0,不计算,result=3,显示"3",num=3。设置calcul=1(加),operate=1。按 4:
command(4):因operate=1,清空旧数,屏幕显示"4"。按 ×:
times()->calculate():此时num=3(非零),quit=0,进入计算分支。根据calcul=1,执行3 + 4,result=7,显示"7",num=7。设置calcul=3(乘),operate=1。按 2:
command(2):屏幕清空后显示"2"。按 =:
equal()->calculate():此时num=7,quit=0,进入计算分支。根据calcul=3,执行7 × 2,result=14,显示"14"。然后`num, result, numshow被重置为0,计算链结束。
这个设计的巧妙之处在于,它模拟了实物计算器“输入数字 -> 按运算符 -> 输入数字 -> 按运算符或等号”的连贯操作体验,通过状态变量(operate, calcul, quit)和中间存储(num)优雅地管理了整个计算流程。