前端实例--JS实现多功能计算器

  1. 开发语言 HTML+CSS+JavaScript

  2. 开发工具 Visual Studio Code

  3. 项目GitHub地址:计算器 (喜欢可以给一个star,阿里嘎多)

  4. 项目运行截图:
    在这里插入图片描述

  5. 技术分析:由于除了简单的四则运算,还需要进行括号匹配,以及优先级的运算。采用后缀表达式的形式进行处理,同时通过模拟栈的特点运用JS自带的数组进行处理。由于代码有详细的注释,所以直接上代码。

  6. 项目代码:
    compute.html:

<!--
 * @Author: CSU_XZY
 * @Date: 2020-10-15 21:17:33
 * @LastEditors: CSU_XZY
 * @LastEditTime: 2020-10-16 22:07:08
 * @FilePath: \第二天\计算器\compute.html
 * @Description: just to play
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>计算器</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    body{
        background-color: #FCFDFE;
    }
    .container{
        overflow: hidden;
        box-shadow: 0 0 3px 0 rgba(0, 0, 0, .3);
        margin: 150px auto;
        width: 548px;
        height: 274px;
        background-color: #fff;
    }
    .box{
        background-color: #fcfdff;
        margin: 15px auto;
        overflow: hidden;
        width: 514px;
        height: 244px;
    }
    .number{
        width: 514px;
        height: 189px;
    }
    .text{
        width: 514px;
        height: 55px;
        margin: 0;
    }
    span{
        border-top: solid 1px #ebebeb;
        border-right: solid 1px #ebebeb;
        box-sizing: border-box;
        float: left;
        display: block;
        width: 25%;
        font-size: 16px;
        color: #333;
        background-color: #fff;
        line-height: 37px;
        cursor: pointer;
        text-align: center;
        font-weight: 10px;
    }
    span:hover{
        background-color: #d3d7d4;
    }
    span:active{
        background-color: #afdfe4;
        
    }
    
    .text>p{
        text-align: right;
        width: 514px;
        height: 24px;
        line-height: 25px;
        font-size: 25px;
    }
    .number>div{
        width: 514px;
        height: 37.8px;
    }
    .around{
        background-color: #f9f9f9;
        color: #f60;
    }
    .compute{
        color: #333;
    }
    .bottom{
        background-color: #fff;
        color: #f60;
    }
    .dot{
        font-size: 23px; 
        font-weight: 19px;
    }
</style>
<body>
    <div class="container">
        <div class="box">
            <div class="text">
                <p id="text"></p>
                <p id="display"></p>
            </div>
            <div class="number">
                <div class="around">
                    <span onclick="showDetails(this)" data-value="(" class="around">(</span>
                    <span onclick="showDetails(this)" data-value=")" class="around">)</span>
                    <span onclick="showDetails(this)" data-value="D" title="回退一位数" class="around">del</span>
                    <span onclick="showDetails(this)" data-value="C" class="around compute">C</span>
                </div>
                <div>
                    <span onclick="showDetails(this)" data-value="7">7</span>
                    <span onclick="showDetails(this)" data-value="8">8</span>
                    <span onclick="showDetails(this)" data-value="9">9</span>
                    <span onclick="showDetails(this)" data-value="÷" class="around">÷</span>
                </div>
                <div>
                    <span onclick="showDetails(this)" data-value="4">4</span>
                    <span onclick="showDetails(this)" data-value="5">5</span>
                    <span onclick="showDetails(this)" data-value="6">6</span>
                    <span onclick="showDetails(this)" data-value="x" class="around">x</span>
                </div>
                <div>
                    <span onclick="showDetails(this)" data-value="1">1</span>
                    <span onclick="showDetails(this)" data-value="2">2</span>
                    <span onclick="showDetails(this)" data-value="3">3</span>
                    <span onclick="showDetails(this)" data-value="-" class="around">-</span>
                </div>
                <div>
                    <span onclick="showDetails(this)" data-value="0">0</span>
                    <span onclick="showDetails(this)" data-value="." class="around bottom dot">.</span>
                    <span onclick="showDetails(this)" data-value="=" class="around bottom">=</span>
                    <span onclick="showDetails(this)" data-value="+" class="around">+</span>
                </div>
            </div>
        </div>
    </div>
</body>
<script type="text/javascript" src="compute.js"></script>
</html>

compute.js:

/*
 * @Author: CSU_XZY
 * @Date: 2020-10-15 21:17:45
 * @LastEditors: CSU_XZY
 * @LastEditTime: 2020-10-17 00:04:41
 * @FilePath: \第二天\计算器\compute.js
 * @Description: just to play
 */
var ysf = ['+','÷','=',')','%','x','-','D'];
var sizeyunsuan = ['+','÷','(','x','-'];
var isNumber = ['1','2','3','4','5','6','7','8','9','0','.'];


function showDetails(number)
{
    var number = number.getAttribute("data-value");
    var text = document.getElementById('display').innerText;
//回退一个文字
    if(number === 'D')
    {
        text = text.substring(0,text.length-1);
        document.getElementById('display').innerHTML=text;
        return;
    }
//判断第一个数字是不是运算符
    else if(judgeBegin(number) && text == "")
    return;
//判断是否是连续两个运算符一起输入
    else if(judgeBegin(number) && judgeNext(text,number) && text[text.length-1] !== ')')
    return;
//判断第一个输入是不是‘.’,如果是变为0.
    else if(number === '.' && text == "")
    number = "0.";
//如果输入归0,清空输入
    else if(number === 'C')
    {
        document.getElementById('text').innerHTML="";
        document.getElementById('display').innerHTML="";
        return;
    }
//输入是等号就判断
    else if(number === '=')
    {
        //将数字与运算符分开
        let array = [];
        let n = text.length;
        for(let i = 0; i < n; i++)
        {
            var JudgeNumber = true;
            let res = "";
            //判断第一个数字是否是负号
            if(i===0 && text[i] === '-')
            {
                res+=text[i];
                i++;
            }
            //判断是不是在运算符之后的减号,是就变为负号
            if(i !== 0 && near(array[array.length-1]) && text[i] === '-')
            {
                res+=text[i];
                i++;
            }
            //判断是否为连续的数字
            while(JudgeIsNumber(text[i]) && i < n)
            {
                res += text[i];
                i++;
                JudgeNumber = false;
            }
            //如果不为数字了要回退一个
            if(JudgeNumber === false)
            i--;
            //判断其他运算符
            if(JudgeNumber === true)
            if(judgeBegin(text[i]) || text[i] === '(' ||  text[i] === '-' || text[i] === ')')
            res+=text[i];
            array.push(res);
        }
        //
            console.log(array);
        //中缀表达式变为后缀表达式
        var hz = houZhui(array);
        console.log(hz);
        var result = compute(hz);
        document.getElementById('text').innerHTML = text;
        document.getElementById('display').innerHTML = result;
        return;
    }
    text+=number;
    document.getElementById('display').innerHTML=text;
}

//判断是不是运算符
function judgeBegin(number)
{
    for(let i = 0; i < ysf.length; i++)
    {
        if(ysf[i] === '-')
        continue;
        if(ysf[i] === number)
        return true;
    }
    return false;
}

//判断是否输入两个连续的运算符
function judgeNext(text,number)
{
    if(number === '-')
    return;
    let a = text.length;
    if(judgeBegin(text[a-1]) && judgeBegin(number))
    return true;
    return false;
}

//判断输入的字符里面是不是数字
function JudgeIsNumber(number){
    for(let i = 0; i < isNumber.length; i++)
    {
        if(isNumber[i] === number)
        return true;
    }
    return false;
}

//判断减号前面是否有别的运算符从而确定是不是负号
function near(number)
{
    for(let i = 0; i < sizeyunsuan.length; i++)
    {
        if(sizeyunsuan[i] === number)
        return true;
    }
    return false;
}

//中缀表达式改为后缀表达式
function houZhui(array)
{
    var stack = [];
    var textArea = [];
    for(let i = 0; i < array.length; i++)
    {
        if(near(array[i]) || array[i] === ')')
        {
            //如果是空直接入栈
            if(stack.length === 0)
            stack.push(array[i]);
            //如果栈顶为左括号直接入栈
            else if(stack[stack.length-1] === '(' && array[i] !== ')')
            stack.push(array[i]);
            //如果输入左括号直接入栈
            else if(array[i] === '(')
            stack.push(array[i]);
            //如果输入的是右括号
            else if(array[i] === ')')
            {
                //一直弹出直到遇到左括号
                while(stack[stack.length-1] !== '(')
                {
                    let a = stack.pop();
                    textArea.push(a);
                }
                //弹出左括号
                stack.pop();
            }
            else if(array[i] === '-' || array[i] === '+')
            {
                while(stack[stack.length-1] !== '(' && stack.length !== 0)
                {
                    let a = stack.pop();
                    textArea.push(a);
                }
                stack.push(array[i]);
            }
            else if(array[i] === 'x' || array[i] === '÷')
            {
                while(stack[stack.length-1] !== '(' && stack[stack.length-1] !== '+' && stack[stack.length-1] !== '-' && stack.length !== 0)
                {
                    let a = stack.pop();
                    textArea.push(a);
                }
                stack.push(array[i]);
            }
        }
        else{
            textArea.push(array[i])
        }
    }
    while(stack.length !== 0)
    {
        let a = stack.pop();
        textArea.push(a);
    }
    return textArea;
}

//计算后缀表达式
function compute(array){
    var NUMBER = [];
    for(let i = 0; i < array.length; i++)
    {
        //是运算符就计算
        if(near(array[i])){
            //加法
            if(array[i] === '+')
            {
                if(NUMBER.length < 2)
                return "错误";
                else
                {
                    let a = NUMBER.pop();
                    let b = NUMBER.pop();
                    let c = a + b;
                    NUMBER.push(c);
                }
            }
            //减法
            else if(array[i] === '-')
            {
                if(NUMBER.length < 2)
                return "错误";
                else
                {
                    let a = NUMBER.pop();
                    let b = NUMBER.pop();
                    let c = b - a;
                    NUMBER.push(c);
                }
            }
            //乘法
            else if(array[i] === 'x')
            {
                if(NUMBER.length < 2)
                return "错误";
                else
                {
                    let a = NUMBER.pop();
                    let b = NUMBER.pop();
                    let c = a * b;
                    NUMBER.push(c);
                }
            }
            //除法
            else if(array[i] === '÷')
            {
                if(NUMBER.length < 2)
                return "错误";
                else
                {
                    let a = NUMBER.pop();
                    let b = NUMBER.pop();
                    if(a === 0)
                    return "0不能作为除数";
                    let c = b / a;
                    NUMBER.push(c);
                }
            }
        }
        else{
            if(array[i][0] === '-')
            {
                let temp = array[i].substring(1,array[0].length);
                let num = parseFloat(temp);
                num = -num;
                NUMBER.push(num);
            }
            else{
                let num = parseFloat(array[i]);
                NUMBER.push(num);
            }
            console.log(NUMBER);
        }
    }
    if(NUMBER.length !== 1)
    return "错误";
    else
    {
        let b = String(NUMBER[0]);
        return b;
    }
}
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值