使用原生js写一个简易计算器

320 阅读4分钟

前言

最近在使用PC端自带计算器时突发奇想,可以写一个简易版的计算器将基础的html、css与js都运用到。

最终效果图

Snipaste_2022-06-24_15-41-09.png

html部分

html部分主要分为显示区域操作区域两部分,而显示区域包括上方的灰色暂留数据区及下方的结果区。这一部分只需注意将类名划分清楚,以便js书写代码时方便dom操作。

 <div class="box">
        <div class="display">
            <div class="small"></div>
            <div class="large"></div>
        </div>
        <ul class="action">
            <li> <a href="javascript:;" class="number">1</a> </li>
            <li> <a href="javascript:;" class="number">2</a> </li>
            <li> <a href="javascript:;" class="number">3</a> </li>
            <li> <a href="javascript:;" class="calculate">+</a> </li>
            <li> <a href="javascript:;" class="number">4</a> </li>
            <li> <a href="javascript:;" class="number">5</a> </li>
            <li> <a href="javascript:;" class="number">6</a> </li>
            <li> <a href="javascript:;" class="calculate">-</a> </li>
            <li> <a href="javascript:;" class="number">7</a> </li>
            <li> <a href="javascript:;" class="number">8</a> </li>
            <li> <a href="javascript:;" class="number">9</a> </li>
            <li> <a href="javascript:;" class="calculate">x</a> </li>
            <li> <a href="javascript:;" class="number">0</a> </li>
            <li> <a href="javascript:;" class="clear">C</a> </li>
            <li> <a href="javascript:;" class="result">=</a> </li>
            <li> <a href="javascript:;" class="calculate">÷</a> </li>
        </ul>
    </div>

css部分

对于按键部分,笔者是采用浮动来布局,如果大家感兴趣也可以采用flex布局。 为了美观,笔者给计算按键都额外增加了颜色。

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
.box {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    padding: 30px 0;
    margin: 30px auto;
    width: 500px;
    height:550px;
    border-radius: 20px;
    border: 1px solid #000;
    background-color: #f1f3f7;
}
.box .display {
    width: 440px;
    height:150px;
    border-radius: 20px;
    border: 1px solid #000;
    background-color: #ffffff;
   
}
.box .display .small {
    width: 440px;
    height: 50px;
    padding-right: 50px;
    font-size: 14px;
    text-align: right;
    line-height: 50px;
    color: gray;
}
.box .display .large{
    width: 440px;
    height: 100px;
    padding-right: 50px;
    font-size: 20px;
    text-align: right;
    line-height: 100px;
}
.box ul {
    width: 440px;
    list-style: none;
    margin-top: 50px;
}
.box ul li {
    float: left;
    width: 105px;
    height: 50px;
    margin: 2px;
    font-size: 20px;
    line-height: 50px;
    border: 1px solid #000;
    border-radius: 5px;
    text-align: center;
    background-color: #ffffff;
}
.box ul li a {
    display: block;
    width: 100%;
    height: 100%;
    text-decoration: none;
    color: #000;
}
.box ul .calculate,.box ul .result {
    background-color: orange;
}
.box ul .clear {
    background-color: aqua;
}

js部分

因为所有操作都是按钮的点击事件,所以直接使用事件委托,给父盒子action注册点击事件,各种按键的判断条件使用e.target.classList.contains('类名')

document.querySelector('.action').addEventListener('click', function (e) {}

一、数字按键

数字按键按下后需实现屏幕显示数字功能。

 if (e.target.classList.contains('number')) {
        document.querySelector('.large').innerHTML += e.target.innerHTML
    }

二、计算按键

计算按键按下后,有三个主要步骤

(1)将数字赋值给num1作为第一个数

(2)保存当前为何种计算操作,方便等号按键按下后进行判断

(3)灰色屏幕上显示当前进行的操作并清空结果显示屏幕

else if (e.target.classList.contains('calculate')) {
            num1 = +document.querySelector('.large').innerHTML
            document.querySelector('.large').innerHTML = ''
            calculate = e.target.innerHTML
            document.querySelector('.small').innerHTML = num1 + calculate
    }

三、等号按键

此阶段逻辑较为复杂

等号按键按下后,有一下4个主要步骤

(1)将当前显示的数字赋值给num2

(2)根据之前保存的计算操作判断,进行相应的加减乘除并显示。

(3)将num2赋值给num1,清空保存的计算操作,以便紧接着计算

(4)灰色屏幕上显示之前的操作

else if (e.target.classList.contains('result')) {
        num2 = +document.querySelector('.large').innerHTML
        switch (calculate) {
            case '+':
                document.querySelector('.large').innerHTML = num1 + num2
                break;
            case '-':
                document.querySelector('.large').innerHTML = num1 - num2
                break;
            case 'x':
                document.querySelector('.large').innerHTML = num1 * num2
                break;
            case '÷':
                document.querySelector('.large').innerHTML = num1 / num2
                break;
            default:
                break;

        }
        num1 = num2
        calculate = ''
         document.querySelector('.small').innerHTML = document.querySelector('.small').innerHTML + num2 + '='
    }

四、清除按键

按下清除按键将所有变量变成初始值。

    else if (e.target.classList.contains('clear')) {
        num1 = 0
        num2 = 0
        calculate = ''
        document.querySelector('.large').innerHTML = ''
        document.querySelector('.small').innerHTML = ''
    }
})

五、功能优化

1、解决连续按下计算按键时出现的问题

连续按下计算按键会直接连续计算,与一般计算器实现效果不符

解决方法: 利用开关阀思想,让用户在按下计算按键后,紧接着按下计算按键,计算按键的点击事件不会触发

具体操作:

(1)设置flag初始值为true

(2)按下数字键flag变成true,按下计算按键flag变成false

(3)给计算按键触发添加判断条件,只有当flag为true时才能触发

2、解决连续按下等号按键出现的问题

连续按下等号,灰色屏幕会出现多个等号

解决办法:

使用indexOf判断灰色屏幕是否包含=字符串,如果包含,只需将结果屏幕上的内容加上=字符串重新赋值给灰色屏幕

使用到的语法:

字符串.indexOf('内容')===-1

用于判断字符串是否包含内容,若包含结果为true,反之为false

js部分全部代码

document.querySelector('.large').innerHTML = ''
let num1 = 0
let num2 = 0
let calculate = ''
let small = ''
let flag = true
document.querySelector('.action').addEventListener('click', function (e) {
    // 一.数字按键
    if (e.target.classList.contains('number')) {
        document.querySelector('.large').innerHTML += e.target.innerHTML
        flag = true
    }
    // 二.运算符按键
    else if (e.target.classList.contains('calculate')) {
        if (flag) {
            num1 = +document.querySelector('.large').innerHTML
            document.querySelector('.large').innerHTML = ''
            calculate = e.target.innerHTML
            document.querySelector('.small').innerHTML = num1 + calculate
            flag = false
        }
    }
    // 三.等号按键
    else if (e.target.classList.contains('result')) {
        num2 = +document.querySelector('.large').innerHTML
        switch (calculate) {
            case '+':
                document.querySelector('.large').innerHTML = num1 + num2
                break;
            case '-':
                document.querySelector('.large').innerHTML = num1 - num2
                break;
            case 'x':
                document.querySelector('.large').innerHTML = num1 * num2
                break;
            case '÷':
                document.querySelector('.large').innerHTML = num1 / num2
                break;
            default:
                break;

        }
        num1 = num2
        calculate = ''
        if (document.querySelector('.small').innerHTML.indexOf('=') === -1) {
            document.querySelector('.small').innerHTML = document.querySelector('.small').innerHTML + num2 + '='
        } else {
            document.querySelector('.small').innerHTML = document.querySelector('.large').innerHTML + '='
        }

    }
    // 四.清除按键
    else if (e.target.classList.contains('clear')) {
        num1 = 0
        num2 = 0
        calculate = ''
        document.querySelector('.large').innerHTML = ''
        document.querySelector('.small').innerHTML = ''
    }
})

总结

通过写这样一个小案例,可以帮助自己熟悉html的书写、css布局、js的简单逻辑与dom操作,还可以帮助自己思考如何优化功能。