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

知识的价值不在于占有,而在于使用。这篇文章主要讲述前端 JavaScript 实现一个简易计算器相关的知识,希望能为你提供帮助。
前端使用 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-width: 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; width: 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; width: 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; width: 75px; } .buttons .btn { width: 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 = https://www.songbingjia.com/android/{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 = https://www.songbingjia.com/android/target.innerText; if (action === /'num\' || action === \'operator\') { that.result(value, action === \'num\'); } }); }, result: function (action, isNum) { var that = this; var data = https://www.songbingjia.com/android/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

【前端 JavaScript 实现一个简易计算器】可以看到,这个是不符合要求的。
还有一个问题需要注意:小数的相加结果可能并不符合预期,比如:
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

~
~ 本文完
~

    推荐阅读