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

家园网

计算器分析

网络 作者:本站 点击:

一、完整代码:

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、运行图:

360截图20260228221831765.jpg


二、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"



    1. 最外层:(str!="0") ? ... : ""。判断当前显示 str 是否不等于 "0"


    2. 内层:((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";
        }


  • 这个函数最简单,它将所有‌核心变量重置为初始状态‌,并将屏幕显示清零。注意它‌没有重置 operatecalculquit‌,这是一个小特点(或小缺陷),但通常不影响使用,因为按下 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。这告诉后续的 commanddot 等函数:“我刚按了运算符,下一个输入的数字是新操作数的开始,请清屏。”


  • 第63行 calcul=1;‌: 将计算状态标志设为 1,代表“加法”。这个值会被 calculate() 函数在下一次运算时使用。

减法(minus)、乘法(times)、除法(divide)、求余(persent)函数逻辑完全相同,只是 calcul 的值分别设为 2345

第五部分:等号函数 equal() (第78-84行)

        function equal(){            calculate();
            operate=1;
            num=0;
            result=0;
            numshow="0";
        }


  • 第79行 calculate();‌: 调用计算函数,执行最后一次运算。


  • 第80行 operate=1;‌: 和运算符一样,设置输入状态,等待新输入。


  • 第81-83行‌: ‌与运算符函数的唯一区别!‌ 它将 numresultnumshow ‌全部重置‌。这意味着按下等号后,‌计算链条被完全切断‌。如果再按运算符,会以当前显示结果为起点开始新的计算。

第六部分:核心计算函数 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 可以清除内部浮动元素可能造成的高度塌陷问题。


    • 通过 borderpadding-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 类(可能应用于 CDEL% 等按钮)被赋予了 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 清除浮动,确保自己在新行显示。


总结:设计逻辑与构思


  1. 层次与结构‌: 通过背景色的深浅变化 (#e2e2e2 -> #f2f2f2 -> #eaeaea),清晰地构建了“页面-计算器面板-按钮”的三层视觉层次,使界面结构一目了然。


  2. 网格化布局‌: 利用 float:left 配合固定宽高和边距,以最简洁的CSS实现了计算器按钮的网格布局,代码高效且兼容性好。


  3. 拟物化与扁平化结合‌:


    • 拟物化‌: 显示屏的“内凹”边框、按钮按下 (:active) 时的颜色变化,都模拟了物理设备的交互反馈。


    • 扁平化‌: 整体使用纯色块、无渐变、无复杂阴影,符合现代简洁的UI设计趋势。



  4. 清晰的视觉分类‌: 通过为工具按钮 (.tool) 设置不同的默认色和激活色,在视觉上将数字键、运算符键和功能键区分开,提升了界面的可读性和易用性。


  5. 完整的交互反馈闭环‌: 设计了 :hover(悬停)和 :active(按下)两种状态,为用户操作提供了即时、明确的视觉反馈,极大地提升了用户体验。


  6. 细节考量‌: 考虑了文字垂直居中、错误信息突出显示、次要信息弱化、布局清除等细节,使得整个计算器看起来精致、专业。

        总而言之,这份CSS代码的构思是‌以用户体验为中心‌,通过严谨的盒模型控制、精心的颜色选择和完整的交互状态定义,将一个由HTML列表和输入框组成的简单结构,美化成了一个直观、美观、反应灵敏的虚拟计算器界面。

四、计算器制作逻辑分析

        代码实现了一个在网页上运行的简单计算器,包含了基本的四则运算、求余、清零、退格等功能。

(一)整体结构与初始化


  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 : "") : ""; 这是一个三层判断:



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


  4. 更新显示与状态‌:将新的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)优雅地管理了整个计算流程。




标签: