您好!欢迎访问家园网-www.jy.wang!

家园网

计算器

网络 作者:本站 点击:
<!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计算器代码的逻辑。这个代码实现了一个在网页上运行的简单计算器,包含了基本的四则运算、求余、清零、退格等功能。

一、整体结构与初始化

  1. HTML骨架‌:代码是一个完整的HTML文件,包含<head><body>。计算器的界面通过HTML元素(如<input>输入框和<li>列表项作为按钮)构建。

  2. 核心变量初始化‌(代码开头部分):

    • 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)函数处理。

  1. 获取当前显示‌:var str=String(document.calculator.numScreen.value); 获取屏幕上显示的内容。

  2. 判断显示重置条件‌:

    • 如果当前显示‌不是‌"0":

    • 如果当前显示‌就是‌"0",则str变为空字符串""(避免在"0"前面追加数字)。

    • operate==0(未按运算符),则str保持原值(继续追加数字)。

    • operate==1(刚按了运算符),则str变为空字符串""(清空旧数,准备输入新数)。

    • str=(str!="0") ? ((operate==0) ? str : "") : ""; 这是一个三层判断:

    • 追加新数字‌:str=str + String(num); 将按下的数字键追加到字符串末尾。

    • 更新显示与状态‌:将新的str显示在屏幕上,并将operatequit重置为0,表示进入正常的数字输入状态。

    举例‌:屏幕上显示"12",此时按"3"。因为operate=0str保持"12",追加"3"后变成"123"显示。如果先按了"+"键(operate=1),再按"3",则str先被清空为"",再追加"3",显示为"3"。

    三、特殊输入处理

    1. 小数点(dot())‌:

      • 先按command函数的逻辑判断是否要清屏。

      • 关键:用一个for循环检查当前字符串‌是否已包含小数点‌(.)。如果已包含,函数直接返回(return false),不再添加,确保一个数字最多只有一个小数点。

      • 如果没有小数点,则在末尾追加"."。

    2. 双零(dzero())‌:

      • 逻辑类似,但追加的是"00"。主要用于快速输入整百、整千等数字。

    3. 退格(del())‌:

      • 获取当前字符串,如果不是"0",就使用substr方法截取掉最后一个字符。

      • 如果截取后字符串为空,则显示"0"。

    4. 清零(clearscreen())‌:

      • 最简单直接:将所有核心变量(numresultnumshowoperatecalculquit)恢复为初始状态。

      • 将屏幕显示重置为"0"。

    四、运算逻辑(核心)

    这是代码最精彩的部分,采用了一种“延迟计算”的模式:‌不是在你按下等号时才计算,而是在你按下下一个运算符时,才计算上一个运算符的表达式。

    步骤分解:

    第一步:按下运算符(如plus()加号)

    1. 立即调用calculate()函数(‌这里开始计算上一个操作‌,如果是第一次按运算符,则只是存储数字)。

    2. 设置operate=1,告诉输入逻辑“下一个按键是新数字的开始”。

    3. 设置calcul=1(对于plus函数),记录“接下来要执行的运算是加法”。

    第二步:calculate()计算函数详解

    1. 获取当前显示值‌:numshow=Number(...) 将屏幕上显示的字符串转为数字。

    2. 判断是否真正需要计算‌:if(num!=0 && quit!=1) 这是关键。

      • num!=0:判断是否已有存储的第一个运算数(num)。如果是第一次按运算符,num为0,不进入计算分支,只做存储。

      • quit!=1:防止重复按键。一旦进入计算分支,会设置quit=1,如果紧接着再按其他运算符,就不会重复计算。

    3. 如果进入计算分支(if内)‌:

      • 根据之前存储的calcul标志(1,2,3,4,5),使用switch语句,用存储的num(第一个数)和当前的numshow(刚输入的第二个数)进行相应的计算,结果存入result

      • 特别注意除法‌:增加了除零判断。如果除数为0,则在页面ID为note的元素(代码中未显示但逻辑存在)显示错误提示,4秒后清除。

      • 设置quit=1,防止本次计算被下一个运算符重复触发。

    4. 如果不进入计算分支(else内)‌:

      • 说明是第一次按运算符,没有前序运算。直接将当前显示的数字numshow赋给result

    5. 更新显示与存储‌:

      • 将计算结果result转为字符串,显示在屏幕上。

      • num=result; ‌这是核心中的核心‌:将本次的计算结果存储到num中,作为‌下一次运算的第一个数‌。这就实现了连续计算(如 3 + 4 + 5)。

    第三步:输入下一个数字

    • 由于operate=1command函数会清空屏幕,然后输入新数字。

    第四步:按下等号(equal())

    1. 调用calculate(),执行最后一次运算。

    2. 设置operate=1

    3. 关键区别‌:它将numresultnumshow全部归零。这意味着等号之后,计算链条被‌重置‌。如果再按数字,会从"0"开始;如果再按运算符,会以当前显示结果为起点开始新的计算链。

    五、界面与交互

    • 显示框‌:<input type="text" name="numScreen" ... onfocus="this.blur();" />onfocus="this.blur()"使得点击输入框时自动失去焦点,防止键盘弹出,强制用户使用屏幕按钮操作。

    • 按钮‌:每个<li>元素都通过onclick事件绑定到对应的函数。数字按钮绑定command(),运算符绑定各自的函数,功能键绑定del()clearscreen()等。

    逻辑总结与流程示例

    计算 3 + 4 × 2 = 的流程:

    1. 按 ‌3‌:command(3) -> 屏幕显示"3"。

    2. 按 ‌+‌:plus() -> calculate():因num=0,不计算,result=3,显示"3",num=3。设置calcul=1(加),operate=1

    3. 按 ‌4‌:command(4):因operate=1,清空旧数,屏幕显示"4"。

    4. 按 ‌×‌:times() -> calculate():此时num=3(非零),quit=0,进入计算分支。根据calcul=1,执行3 + 4result=7,显示"7",num=7。设置calcul=3(乘),operate=1

    5. 按 ‌2‌:command(2):屏幕清空后显示"2"。

    6. 按 ‌=‌:equal() -> calculate():此时num=7quit=0,进入计算分支。根据calcul=3,执行7 × 2result=14,显示"14"。‌然后`num, result, numshow被重置为0‌,计算链结束。

    这个设计的巧妙之处在于,它模拟了实物计算器“输入数字 -> 按运算符 -> 输入数字 -> 按运算符或等号”的连贯操作体验,通过状态变量(operatecalculquit)和中间存储(num)优雅地管理了整个计算流程。


    标签: