<!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>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;
}解析:
为你详细分步讲解这个JavaScript计算器代码的逻辑。这个代码实现了一个在网页上运行的简单计算器,包含了基本的四则运算、求余、清零、退格等功能。
一、整体结构与初始化
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)优雅地管理了整个计算流程。