前言
本文主要讲解如何用纯前端制作计算器,并且可以利用鼠标点击、键盘监听、键盘连续键监听实现加减乘除、delete、计算结果、清除全部数字等功能。那么好文本正式开始。
布局和样式流程
首先是HTML+CSS结构:这里主要用到的是position定位和Flex布局。
- 首先我们准备一个大的div,用于装最大的容器,它的id为all
- 然后我们准备三个小的div,给这些div加上Flex-box弹性盒子布局
- 这三个小div下面准备了四个小div,四个小div主要用到的是flex:1,均匀的进行平分上述div的空间
- 那么同时我们在最上面的0展示阶段设置了两个div
- 第一个div用到的是position:absolute,绝对定位,top:40px;right:0px
- 第二个div就是为了占据第一个div的空间,因为绝对定位不占用页面空间,但是我们还想要留出这部分空间,所以使用另一个普通的div来实现这块空间的占据。
JS实现流程
- 我们使用事件委托来实现一个事件绑定所有计算器中能看到的按钮和最终值的id。想了解事件委托的小伙伴可以点击我的另一篇文章:点击这里
- 简单来说,事件委托就是在父元素的监听事件下去绑定所有符合要求的子元素,那么就实现一个事件多次复用和简化代码的操作了。
- 首先我们定义两个变量,分别存储id为all的DOM父元素,和最终结果展示区域也就是ansDOM子元素
- 给all添加一个点击监听事件
- 如果这个事件对象下点击的目标对象下的
className
伪类名是flex_1,那么我就进入这个循环,这里flex_1
是所有按钮都绑定的一个伪类,那么就可以用于判断。 - 用
innerHTML
判断获取到的点击元素的内容,比如点击=内容为=,点击+为+等等,然后去做对应的逻辑处理。最后用parseInt进行字符串转换数字操作,然后赋值给result变量,最终给ans变量的innerHTML
赋值。实现计算器效果。
全部源码
<!DOCTYPE html>
<html><head><style>* {padding: 0;margin: 0;}.container {width: 320px;background-color: #fafafa;border: 1px solid lightgray;position: relative;box-shadow: 1px 1px 15px lightgray;margin: 0 auto 0 auto;margin-top: 150px;}.contain {display: flex;justify-content: center;align-items: center;}.flex_1 {text-align: center;border: 1px solid lightgray;background-color: white;color: black;flex: 1;font-size: 24px;line-height: 50px;}#ans {height: 50px;position: absolute;top: 30px;right: 0;font-size: 24px;line-height: 50px;}</style></head><body><div class="container" id="all"><div style="position:absolute;top:10px;left:10px;font-size:12px">计算器</div><div style="position:absolute;top:160px;right:5px;" id="ans">0</div><div style="height:200px;"></div><div class="contain"><div class="flex_1">0</div><div class="flex_1">1</div><div class="flex_1">2</div><div class="flex_1">-</div></div><div class="contain"><div class="flex_1">3</div><div class="flex_1">4</div><div class="flex_1">5</div><div class="flex_1">+</div></div><div class="contain"><div class="flex_1">6</div><div class="flex_1">7</div><div class="flex_1">8</div><div class="flex_1">*</div></div><div class="contain"><div class="flex_1">9</div><div class="flex_1">÷</div><div class="flex_1">AC</div><div class="flex_1">=</div></div></div><script>let ans = document.getElementById('ans')let lastKeyCode = null;document.getElementById('all').addEventListener('click', function(e) {if (e.target.className == 'flex_1') {if (ans.innerHTML == 0) {switch (e.target.innerHTML) {case 'AC':break;case '=':break;case '+':break;case '-':break;case '*':break;case '÷':break;default:ans.innerHTML = e.target.innerHTML}} else if (e.target.innerHTML == 'AC') {ans.innerHTML = 0} else if (e.target.innerHTML == '=') {computeResult()} else if (ans.innerHTML.length < 22) {ans.innerHTML += e.target.innerHTML}}})document.onkeydown = function(e) {if (lastKeyCode != 16) {if ((e.keyCode <= 57 && e.keyCode >= 47) ||(e.keyCode <= 105 && e.keyCode >= 96)) {if (ans.innerHTML.length < 22) {let temp = e.keyCode <= 57 ? e.keyCode - 48 : e.keyCode - 96;if (ans.innerHTML == 0) {ans.innerHTML = temp} else {ans.innerHTML += temp;}}} else if (ans.innerHTML.length < 22 || e.keyCode == 8 || e.keyCode == 187 ||e.keyCode == 13) {ans.innerHTML = keyMany()switch (e.keyCode) {case 189:if (ans.innerHTML.length < 22)ans.innerHTML += '-';break;case 191:if (ans.innerHTML.length < 22)ans.innerHTML += '÷';break;case 8:ans.innerHTML = ans.innerHTML.length >= 1 ? ans.innerHTML.slice(0, ans.innerHTML.length -1) : '';break;case 13:computeResult();break;case 187:computeResult();break;}}} else if (ans.innerHTML.length < 22) {if (e.keyCode == 187) {ans.innerHTML = keyMany()ans.innerHTML += '+'} else if (e.keyCode == 56) {ans.innerHTML = keyMany()ans.innerHTML += '*'}}if (lastKeyCode == null) {lastKeyCode = e.keyCode}}document.onkeyup = function(e) {lastKeyCode = null}function keyMany() {let temp = ans.innerHTML[ans.innerHTML.length - 1]if (temp == '+' || temp == '-' || temp == '÷' || temp == '*') {ans.innerHTML = ans.innerHTML.slice(0, ans.innerHTML.length - 1)console.log(ans.innerHTML);}return ans.innerHTML;}function computeResult() {let arr = Array.from(ans.innerHTML)let startData = '',sym = '',endData = ''arr.forEach((item, index) => {if (index == 0 && item == '-') {startData = '0'sym = '-'}else if (isSym(item)) {if (sym != '') {switch (sym) {case '+':startData = Number(startData) + Number(endData);break;case '-':startData = Number(startData) - Number(endData);break;case '*':startData = Number(startData) * Number(endData);break;case '÷':startData = Number(startData) / Number(endData);break;}endData = '';}sym = item;} else {if (startData == '' || sym == '') {startData += item} else {if (index == arr.length - 1) {if (!isSym(arr[index])) {endData += item;}switch (sym) {case '+':startData = Number(startData) + Number(endData);break;case '-':startData = Number(startData) - Number(endData);break;case '*':startData = Number(startData) * Number(endData);break;case '÷':startData = Number(startData) / Number(endData);break;}endData = '';} else {endData += item;}}}})ans.innerHTML = startData}function isSym(data) {if (data == '+' || data == '-' || data == '*' || data == '÷') {return true;} else {return false;}}</script></body>
</html>