• 前端 JavaScript 实现一个简易计算器


    前端使用 JavaScript 实现一个简易计算器,没有难度,但是里面有些小知识还是需要注意的,算是一次基础知识回顾吧。

    题目

    计算器

    实现一个简易版的计算器,需求如下:

    1、除法操作时,如果被除数为0,则结果为0
    2、结果如果为小数,最多保留小数点后两位,如 2 / 3 = 0.67(显示0.67), 1 / 2 = 0.5(显示0.5)
    3、请阅读并根据提示补充完成函数initEvent、result和calculate
    4、请不要手动修改html和css
    5、不要使用第三方插件

    实现

    HTML 文件

    <div class="calculator">
        <header class="cal-header">简易计算器</header>
        <main class="cal-main">
            <div class="origin-value">0</div>
            <div class="cal-keyboard">
                <ul class="cal-items">
                    <li data-action="num">7</li>
                    <li data-action="num">8</li>
                    <li data-action="num">9</li>
                    <li data-action="operator">÷</li>
                    <li data-action="num">4</li>
                    <li data-action="num">5</li>
                    <li data-action="num">6</li>
                    <li data-action="operator">x</li>
                    <li data-action="num">1</li>
                    <li data-action="num">2</li>
                    <li data-action="num">3</li>
                    <li data-action="operator">-</li>
                    <li data-action="num">0</li>
                    <li data-action="operator">清空</li>
                    <li data-action="operator">=</li>
                    <li data-action="operator">+</li>
                </ul>
            </div>
        </main>
    </div>
    

    CSS 文件

    body, ul, li,select {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    ul,li {list-style: none;}
    .calculator {
        max- 300px;
        margin: 20px auto;
        border: 1px solid #eee;
        border-radius: 3px;
    }
    .cal-header {
        font-size: 16px;
        color: #333;
        font-weight: bold;
        height: 48px;
        line-height: 48px;
        border-bottom: 1px solid #eee;
        text-align: center;
    }
    .cal-main {
        font-size: 14px;
    }
    .cal-main .origin-value {
        padding: 15px;
        height: 40px;
        line-height: 40px;
        font-size: 20px;
        text-align: right;
        overflow: hidden;
        text-overflow:ellipsis;
        white-space: nowrap;
    }
    .cal-main .origin-type,
    .cal-main .target-type {
        padding-left: 5px;
         70px;
        font-size: 14px;
        height: 30px;
        border: 1px solid #eee;
        background-color: #fff;
        vertical-align: middle;
        margin-right: 10px;
        border-radius: 3px;
    }
    .cal-keyboard {
        overflow: hidden;
    }
    .cal-items {
        overflow: hidden;
    }
    .cal-items li {
        user-select: none;
        float: left;
        display: inline-block;
         75px;
        height: 75px;
        text-align: center;
        line-height: 75px;
        border-top: 1px solid #eee;
        border-left: 1px solid #eee;
        box-sizing: border-box;
    }
    li:nth-of-type(4n+1) {
        border-left: none;
    }
    li[data-action=operator] {
        background: #f5923e;
        color: #fff;
    }
    .buttons {
        float: left;
         75px;
    }
    .buttons .btn {
         75px;
        background-color: #fff;
        border-top: 1px solid #eee;
        border-left: 1px solid #eee;
        height: 150px;
        line-height: 150px;
        text-align: center;
    }
    .btn-esc {
        color: #ff5a34;
    }
    .btn-backspace {
        position: relative;
    }
    

    JavaScript 文件

    var Calculator = {
        init: function () {
            var that = this;
            if (!that.isInited) {
                that.isInited = true;
                // 保存操作信息
                // total: Number, 总的结果
                // next: String, 下一个和 total 进行运算的数据
                // action: String, 操作符号
                that.data = {total: 0, next: '', action: ''};
                that.bindEvent();
            }
        },
        bindEvent: function () {
            var that = this;
            // 获取 .cal-keyboard 元素
            var keyboardEl = document.querySelector(".cal-keyboard");
            keyboardEl && keyboardEl.addEventListener('click', function (event) {
                // 获取当前点击的dom元素
                var target = event.target;
                // 获取target的 data-action 值
                var action = target.dataset.action;
                // 获取target的内容
                var value = target.innerText;
                if (action === 'num' || action === 'operator') {
                    that.result(value, action === 'num');
                }
            });
        },
        result: function (action, isNum) {
            var that = this;
            var data = that.data;
            if (isNum) {
                data.next = data.next === '0' ? action : (data.next + action);
                !data.action && (data.total = 0);
            } else if (action === '清空') {
                // 设置清空时的对应状态
                data.total = 0;
                data.next = "";
                data.action = "";
            } else if (action === '=') {
                if (data.next || data.action) {
                    data.total = that.calculate(data.total, data.next, data.action);
                    data.next = '';
                    data.action = '';
                }
            } else if (!data.next) {
                data.action = action;
            } else if (data.action) {
                data.total = that.calculate(data.total, data.next, data.action);
                data.next = '';
                data.action = action;
            } else {
                data.total = +data.next || 0;
                data.next = '';
                data.action = action;
            }
    
            // 获取 .origin-value 元素
            var valEl = document.querySelector(".origin-value");
            // print(data)
            valEl && (valEl.innerHTML = data.next || data.total || '0');
        },
        calculate: function (n1, n2, operator) {
            n1 = +n1 || 0;
            n2 = +n2 || 0;
            if (operator === '÷') {
                // 获取除法的结果
                return n2 === 0 ? 0 : Math.floor((n1 / n2) * 100) / 100;
            } else if (operator === 'x') {
                // 获取乘法的结果
                return Math.floor((n1 * n2) * 100) / 100;
            } else if (operator === '+') {
                // 获取加法的结果
                return Math.floor((n1 + n2) * 100) / 100;
            } else if (operator === '-') {
                // 获取减法的结果
                return Math.floor((n1 - n2) * 100) / 100;
            }
        }
    };
    Calculator.init();
    

    分析

    主要分析一下本题中 JavaScript 部分涉及的知识点。

    事件委托

    我们没有给数字和符号元素分别添加点击事件,而是通过给它们的父元素 .cal-keyboard 添加点击事件,再通过事件冒泡获得它父元素绑定的事件响应,使用事件委托有以下优点:

    • 减少内存消耗
    • 可以方便地动态添加或者删除元素
    • 管理的函数减少
    • 减少操作 DOM 节点的次数,提高性能

    事件委托的步骤:

    1. 给父元素绑定响应事件
    2. 监听子元素的冒泡事件
    3. 获取触发事件的目标元素

    保留小数位

    大家的第一反应可能是使用 toFixed() 方法,但是这个方法在小数位不足的情况下会在后面补 0,比如:

    const num = 0.8;
    num.toFixed(2) // 0.80
    

    可以看到,这个是不符合要求的。

    还有一个问题需要注意:小数的相加结果可能并不符合预期,比如:

    console.log(0.2 + 0.4) // 0.6000000000000001
    

    这里我们建议使用 Math.floor() 方法来处理小数位,先给结果乘以 100,再通过 Math.floor() 取得整数部分,然后除以 100,得到符合要求的结果,比如:

    const num1 = 0.5;
    const num2 = 0.68751;
    Math.floor(num1 * 100)/100   	// 0.5
    Math.floor(num2 * 100)/100		// 0.68
    
    ~
    本文完

    ~

    学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!

    大家好,我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!

    你来,怀揣期望,我有墨香相迎! 你归,无论得失,唯以余韵相赠!

    知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!

  • 相关阅读:
    原子核结构壳模型:粒子空穴转换
    第十二周学习总结
    构建之法读书笔记5
    5.21学习总结——android开发实现用户头像的上传
    5.20团队活动
    构建之法读书笔记4
    团队项目第一阶段验收
    HTML+CSS设计个人主页
    C++文件流
    面向对象程序设计_虚函数的应用
  • 原文地址:https://www.cnblogs.com/bianchengsanmei/p/14991688.html
Copyright © 2020-2023  润新知