前端应用 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 = {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 节点的次数,进步性能
事件委托的步骤:
- 给父元素绑定响应事件
- 监听子元素的冒泡事件
- 获取触发事件的指标元素
保留小数位
大家的第一反馈可能是应用 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
~
~ 本文完
~
学习乏味的常识,结识乏味的敌人,塑造乏味的灵魂!
大家好,我是〖编程三昧〗的作者 隐逸王 ,我的公众号是『编程三昧』,欢送关注,心愿大家多多指教!
你来,怀揣冀望,我有墨香相迎!你归,无论得失,唯以余韵相赠!
常识与技能并重,内力和外功兼修,实践和实际两手都要抓、两手都要硬!