js之win10计算器

前不久完成了win10计算器的页面布局(HTML+CSS),这时间我学习了js的一些技术,现在我继续完成其js部分。
为了便于功能显示,在页面布局部分的代码在上次部分做了稍微改动。
完整代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>calculator</title>
    <link rel="stylesheet" href="calculator.css">
</head>
<body>
    <div class="calculator"> 
        <div class="screen1"><span></span></div>   //新增表达式显示屏(初始时无显示)
        <div class="screen2"><span>0</span></div>
        <div class="M">
            <ul>
                <li class="m">MC</li>
                <li class="m">MR</li>
                <li class="c1 m1">M+</li>
                <li class="c1 m1">M-</li>
                <li class="c1 m1">MS</li>
            </ul>
        </div>
        <div class="row u1">
            <ul>
                <li class="c1">%</li>
                <li class="c1">(</li>
                <li class="c1">)</li>
                <li class="c1">1/x</li>
            </ul>
        </div>
        <div class="row u1">
             <ul>
                <li class="c1">CE</li>
                <li class="c1">C</li>
                <li class="c1">DEL</li>
                <li class="c1">/</li>
            </ul>
        </div>
        <div class="row">
            <ul>
                <li class="c1 u2">7</li>
                <li class="c1 u2">8</li>
                <li class="c1 u2">9</li>
                <li class="c1 u1">*</li>
            </ul>
        </div>
        <div class="row">
            <ul>
                <li class="c1 u2">4</li>
                <li class="c1 u2">5</li>
                <li class="c1 u2">6</li>
                <li class="c1 u1">-</li>
            </ul>
        </div>
        <div class="row">
            <ul>
                <li class="c1 u2">1</li>
                <li class="c1 u2">2</li>
                <li class="c1 u2">3</li>
                <li class="c1 u1">+</li>
            </ul>
        </div>
        <div class="row">
            <ul>
                <li class="c1 u1">+/_</li>
                <li class="c1 u2">0</li>
                <li class="c1 u1">.</li>
                <li class="c1 u1">=</li>
            </ul>
        </div>
    </div>
    <script src="calculator.js"></script>//引入js文件
</body>
</html>
* {
    margin: 0;
    padding: 0;
}

.calculator {
    width: 400px;
    height: 100%;
    background-color: rgb(241, 241, 241);
    overflow: hidden;
    margin: 0 auto;
    //为了美观,适当减少弯角曲率
    border-top-left-radius: 10%;
    border-top-right-radius: 10%;
}

.screen1 {//新增的显示屏的样式
    height: 50px;
    line-height: 50px;
    margin-top: 50px;
    font-size: 20px;
    color: yellowgreen;
}
.screen2 {
    height: 100px;
    font-size: 50px;
    line-height: 100px;
    color: #000;
    font-weight: 600;
}
span {
    float: right;
}

.M {
    margin-top: 20px;
    height: 30px;
}

.M li {
    width: 65px;
    line-height: 30px;
    list-style: none;
    float: left;
    text-align: center;
    font-size: 10px;
}

.m {
    color: rgb(192, 192, 192);
}

.m1 {
    font-weight: 600;
}

.c1{
transition: all 0.5s;
}
.c1:hover {
    background-color: rgb(214, 212, 212);
}

.row {
    height: 80px;
}

.row li {
    width: 100px;
    height: 80px;
    line-height: 70px;
    list-style: none;
    float: left;
    text-align: center;
    border: 2px solid rgb(241, 241, 241);
    box-sizing: border-box;
}

.u1 {
    font-size: 20px;
    background-color: rgb(245, 245, 245);
}

.u2 {
    font-size: 25px;
    font-weight: 700;
    background-color: rgb(255, 255, 255);
}

(页面布局部分的具体详情可以点击以下链接win10计算器页面布局
在开始编写js代码前,首先得明确此功能实现中最重要的两个问题:

  1. 如何找到鼠标点击了哪个li
  2. 如何把结果传给显示屏

对于问题1的处理方法:通过e.target.innerText得到点击事件的li里面的文本内容,然后通过比较来确定执行相应的功能逻辑。
对于问题2的处理方法:document.getElementsByClassName(className)[0].getElementsByTagName(“span”)[0].innerText,它就可以设置显示屏应要显示的内容。
处理掉这两个问题后,实现功能就易如反掌了。

function my$(className) {
    return document.getElementsByClassName(className);
}
var strs = my$("c1");
var flag = false;
for (var i = 0; i < strs.length; i++) {
    strs[i].onclick = function (e) {
        var str = e.target.innerText;
        var tmp = my$("screen1")[0].getElementsByTagName("span")[0].innerText;
        if (str === "=") {
            var a = calculate(tmp);
            //小数显示不下
            my$("screen2")[0].getElementsByTagName("span")[0].innerText = a;
            flag = true;
        } else if (str === "DEL") {
            if (flag) {
                my$("screen1")[0].getElementsByTagName("span")[0].innerText = "";
                flag = false;
            } else {
                tmp = tmp.substring(0, tmp.length - 1);
                my$("screen1")[0].getElementsByTagName("span")[0].innerText = tmp;
            }
        } else if (str === "C" || str === "CE") {
            if (str === "C" || flag) {
                my$("screen1")[0].getElementsByTagName("span")[0].innerText = "";
                my$("screen2")[0].getElementsByTagName("span")[0].innerText = 0;
                flag = false;
            } else {
                my$("screen2")[0].getElementsByTagName("span")[0].innerText = 0;
            }
        } else {
            if (flag) {
                tmp = my$("screen2")[0].getElementsByTagName("span")[0].innerText;
                flag = false;
            }
            if (tmp === "") {
                my$("screen1")[0].getElementsByTagName("span")[0].innerText = str;
            } else {
                my$("screen1")[0].getElementsByTagName("span")[0].innerText = tmp + str;
            }
        }
    }
}

//算数算法
var calculate = function (s) {
    var stack = new Array();
    for (var i = 0; i < s.length; i++) {
        var tmp = s[i];
        if (tmp >= '0' && tmp <= '9') {
            var r = getNum(s, i);
            dealNum(s, stack, r.num);
            i = r.index;
        } else if (tmp === '+' || tmp === '-' || tmp === '*' || tmp === '/' || tmp === '(') {
            stack.push(tmp);
        } else if (tmp === ')') {
            dealRight(s, stack);
        }
    }
    return getFinalResult(stack);
};

var getNum = function (s, i) {
    var start = i;
    while (i < s.length && ((s[i] >= '0' && s[i] <= '9') || s[i] === '.')) {
        i++;
    }
    return {
        num: Number(s.substring(start, i)),
        index: i - 1
    };
};

var dealNum = function (s, stack, num) {
    if (stack.length !== 0 && (stack[stack.length - 1] === '*' || stack[stack.length - 1] === '/')) {
        var sign1 = stack.pop();
        var pre1 = stack.pop();
        var res = sign1 === '*' ? pre1 * num : pre1 / num;
        stack.push(res);
    } else {
        stack.push(num);
    }
}

var dealRight = function (s, stack) {
    var result = 0;
    //括号里面只有+/-运算
    while (stack[stack.length - 1] !== '(') {
        var next1 = stack.pop();
        if (stack.length === 0 || stack[stack.length - 1] === '(') {
            result += next1;
            break;
        }
        var sign2 = stack.pop();
        result = sign2 === '+' ? result + next1 : result - next1;
    }
    stack.pop();
    var res2 = 0;
    //使得stack里面只有+/-运算符,保证算法优先级(原因:完成括号运算后的结果必然是一个数字)
    while (stack.length !== 0 && (stack[stack.length - 1] === '*' || stack[stack.length - 1] === '/')) {
        var sign3 = stack.pop();
        var pre2 = stack.pop();
        res2 = sign3 === '*' ? pre2 * result : pre2 / result;
        result = res2;
    }
    stack.push(result);
}

var getFinalResult = function (stack) {
    var result = 0;
    while (stack.length > 0) {
        var next = stack.pop();
        if (stack.length === 0) {
            return result + next;
        }
        var sign = stack.pop();
        result = sign === '+' ? result + next : result - next;
    }
    return result;
};

解释几个地方:

  1. 由于显示屏的大小以及字体的大小设置不合理而产生如下情况的bug(interesting)在这里插入图片描述
  2. 这里面还有部分功能未实现(包括部分点击事件,算数算法没有支持正负数以及异常输入和异常结果的处理)
  3. 算法部分我采用的是自己编写的算数算法,如果有不懂可以看leetcode772题–基本计算器 III(这题是困难难度,其实就是1,2的综合版),此算法的思路来源 算法思路
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Win10计算器是一个非常实用的工具,在日常使用中起到了很大的帮助作用。但有些时候,我们需要离线安装这个计算器,比如没有网络或者网络不稳定的情况下。 要获得计算器的离线安装包,我们可以去Microsoft官网上下载。首先,我们要确定我们需要哪个版本的计算器,比如标准版、科学版或程序员版。然后,在Microsoft官网上搜索“Win10计算器离线安装包”并进入下载页面。 在下载页面上,我们可以看到各种版本的计算器的下载链接,点击所需的版本进行下载。下载后,我们需双击安装程序并按照指示进行安装到自己的电脑中。 需要注意的是,在离线安装计算器过程中,我们要确保我们下载的安装包是来自于官方渠道。否则,下载到一些恶意软件可能会损害我们电脑的安全。最好的方法是去制造商的网站上下载安装包。 总之,离线安装包具有很大的便利性,适用于一些网络不稳定或不好的情况下,而建议更正规的渠道下载。 ### 回答2: Win10计算器被许多人认为是一款十分实用的应用程序,它可以为用户提供各种计算功能,如科学计算、编程计算、日期计算等等,具有十分广泛的使用价值。但是,在某些情况下,用户可能无法联网使用此应用程序,例如:在网络连接不佳或是在某些工作场所禁止联网的情况下。因此,用户可能希望下载Win10计算器的离线安装包以保证无网络情况下仍能成功运行Win10计算器。 要下载Win10计算器的离线安装包,用户可以打开微软官网,在官网的“软件下载”页面中找到Win10计算器应用程序,并选择适合自己的操作系统版本进行下载。值得注意的是,用户需要根据自己系统的版本下载相应的离线安装包,否则无法成功安装使用。在下载完成后,用户可以双击该安装包进行解压,并按照提示完成安装。 最后提醒用户,下载并使用Win10计算器的离线安装包时需注意安全问题,只下载可靠来源的离线安装包,以防下载并安装到恶意病毒。 ### 回答3: Win10计算器离线安装包是指可以在不联网的情况下使用的安装包,在计算机上实现离线安装计算器的目的。由于一些原因,有些用户可能无法在线下载计算器,或者需要在没有网络的环境下使用计算器。此时,使用Win10计算器离线安装包就是最好的选择之一。 Win10计算器离线安装包可以从Microsoft官方网站上下载得到,用户需要选择对应的操作系统及计算器版本,然后将安装包下载到本地计算机中。下载完成后,可以直接运行安装包进行安装,安装完成后,可以在没有网络的情况下使用计算器Win10计算器离线安装包的好处在于,用户可以在没有网络的情况下随时使用计算器,并且可以保证计算器的稳定性和安全性。同时,离线安装包可以被用户备份,以便在需要时再次使用。 总之,Win10计算器离线安装包是一个很好的选择,可以帮助用户解决一些特殊场景下的计算需求。建议对于需要频繁使用计算器的用户尤其应该下载离线安装包备用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值