原生JS实现计算器(内含源码)

前言

本文主要讲解如何用纯前端制作计算器,并且可以利用鼠标点击、键盘监听、键盘连续键监听实现加减乘除、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实现流程

  1. 我们使用事件委托来实现一个事件绑定所有计算器中能看到的按钮和最终值的id。想了解事件委托的小伙伴可以点击我的另一篇文章:点击这里
  2. 简单来说,事件委托就是在父元素的监听事件下去绑定所有符合要求的子元素,那么就实现一个事件多次复用和简化代码的操作了。
  3. 首先我们定义两个变量,分别存储id为all的DOM父元素,和最终结果展示区域也就是ansDOM子元素
  4. 给all添加一个点击监听事件
  5. 如果这个事件对象下点击的目标对象下的className伪类名是flex_1,那么我就进入这个循环,这里flex_1是所有按钮都绑定的一个伪类,那么就可以用于判断。
  6. 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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/188200.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio - 显示配置

1.修改 Code / Split / Design&#xff08;代码视图 & 效果视图&#xff09; 路径&#xff1a;Settings→Editor→Design Tools。 2.增加打开文件的数量及展示方式 路径&#xff1a;Settings→Editor→General→Editor Tabs。

跨境电商平台的社会责任:可持续经营的路径

随着全球化的不断推进&#xff0c;跨境电商平台在国际贸易中扮演着越来越重要的角色。然而&#xff0c;这一行业的蓬勃发展也伴随着一系列社会和环境问题&#xff0c;使得跨境电商平台不得不正视并履行社会责任。在追求商业成功的同时&#xff0c;平台如何走上一条可持续经营的…

解决VS2019和VS2022项目兼容性问题

近期&#xff0c;我遇到了一个问题&#xff0c;我使用的项目在VS2019中开发&#xff0c;但在被VS2022打开之后&#xff0c;再次在VS2019中打开该项目时&#xff0c;却出现了兼容性问题。在本篇博客中&#xff0c;我将分享解决这个问题的方法。 问题描述 在使用VS2019开发的项…

【网络安全】用永恒之蓝(Eternal blue)测试windows系统的安全性

一、kali默认账户和密码都为kali 攻击机&#xff1a;Linux 的 kali 目标机&#xff1a;Windows7 x64 二、kali、metasploit、metasploit 攻击 windows操作系统、metasploit 攻击 永恒之蓝 全流程 ①kali&#xff1a;是黑客攻击机。开源免费的Linux操作系统&#xff0c;含有300…

2023年亚太杯数学建模C题新能源汽车(思路模型代码)

一、翻译 新能源汽车是指采用先进的技术原理、新技术和新结构&#xff0c;以非常规车用燃料&#xff08;非常规车用燃料是指汽油和柴油以外的燃料(非常规车用燃料是指汽油和柴油以外的燃料&#xff09;&#xff0c;并集成了汽车动力控制和驱动等先进技术的汽车。新能源汽车包括…

理解 Python 的 for 循环

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 在本篇博客中&#xff0c;我们将讨论 Python 中 for 循环的原理。 我们将从一组基本例子和它的语法开始&#xff0c;还将讨论与 for 循环关联的 else 代码块的用…

【技术分享】远程透传网关-单网口快速实现西门子S7-200 串口PLC程序远程上下载

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条&#xff0c;用于实现网络连接一台西门子S7-200 PLC及其编程软件一个9针串口头及连接线&#xff0c;用于连接PLC一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡&#xff0c;WIFI联…

27.Spring如何避免在并发下获取不完整的Bean?

Spring如何避免在并发下获取不完整的Bean? 1、为什么获取不到完整的Bean? 我们知道, 如果spring容器已经加载完了, 那么肯定所有bean都是完整的了, 但如果, spring没有加载完, 在加载的过程中, 构建bean就有可能出现不完整bean的情况 2、如何解决读取到不完整bean的问题. …

使用Docker Compose搭建CIG监控平台

CIG简介 CIG监控平台是基于CAdvisor、InfluxDB和Granfana构建的一个容器重量级监控系统&#xff0c;用于监控容器的各项性能指标。其中&#xff0c;CAdvisor是一个容器资源监控工具&#xff0c;用于监控容器的内存、CPU、网络IO和磁盘IO等。InfluxDB是一个开源的分布式时序、时…

jmeter资料

1.jmeter介绍 Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试&#xff0c;它最初被设计用于Web应用测试&#xff0c;但后来扩展到其他测试领域。 它可以用于测试静态和动态资源&#xff0c;例如静态文件、Java 小服务程序、CGI 脚本、Java 对象…

大数据技术之Kafka:一篇文章带你学会Kafka

大数据技术之Kafka&#xff1a;一篇文章带你学会Kafka 第1章Kafka概述 1.1 消息队列 &#xff08;1&#xff09;点对点模式&#xff08;一对一&#xff0c;消费者主动拉取数据&#xff0c;消息收到后消息清除&#xff09;点对点模型通常是一个基于拉取或者轮询的消息传送模型…

视频怎么去水印?如何下载保存无水印视频?

你是否曾经在观看鬼畜素材视频时&#xff0c;被烦人的水印挡住了视线&#xff0c;让你感到十分郁闷&#xff1f;不要担心&#xff0c;今天我将为你介绍几种经典的方法&#xff0c;让你轻松下载无水印视频&#xff0c;让观看体验更加清爽不留痕迹。让我们一起来试试吧&#xff0…

【PTA题目】7-15 寻找数中连续数字构成的最大素数 分数 20

7-15 寻找数中连续数字构成的最大素数 分数 20 全屏浏览题目 切换布局 作者 叶斌 单位 成都信息工程大学 输入一个整数&#xff0c;找出其中由N(N>1)个连续数字组成的最大素数&#xff0c;如果找不到素数&#xff0c;则输出None。 输入格式: 输入1个正整数。 输出格式…

静态资源地址API字节流访问服务器文件区别及相互兼容方案

静态资源地址&API字节流访问服务器文件区别及相互兼容方案 概述特殊场景分析&猜测解决 概述 访问文件资源&#xff0c;一般常见的有两种方式&#xff1a; 静态资源地址&#xff1a;https://www.baidu.com/aaa.png、https://www.baidu.com/video.mp4接口获取文件流&am…

非空断言,

先看下TypeScript基础之非空断言操作符、可选链运算符、空值合并运算符-CSDN博客 我没有复现出来&#xff0c;但是我知道了它的作用 用 let str: string arg!; 代替 let str: string; if (arg) { str arg; } 非空断言&#xff08;!&#xff09;和不使用的区别在于对于…

【Linux】TCP套接字编程

目录 前言 UDP服务器的完善 线程的封装 结构定义 接口实现 环形队列 结构定义 接口实现 加锁 信号量的申请与释放 入队与出队 整体组装 初始化与析构 信息接收线程 消息发送线程 TCP套接字 创建套接字 listen accept 收发操作 客户端的编写 进一步完善 …

每日一题:LeetCode-1089. 复写零

每日一题系列&#xff08;day 09&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

浅学指针(4)函数指针数组和qsort的使用

系列文章目录 文章目录 系列文章目录前言1.函数指针数组的⽤途作用&#xff1a;可以让代码更简洁&#xff0c;逻辑更清晰 2. 回调函数回调函数就是⼀个通过函数指针调⽤的函数 3 . qsort函数qsort函数可以排序所有数据类型解释如图&#xff1a;![在这里插入图片描述](https://i…

Google Chrome 下载 (离线版)

1 访问网址 Google Chrome 网络浏览器 2 点击 下载Chrome 3 直接运行 ChromeStandaloneSetup64.exe 其他&#xff1a; ####################### 谷歌浏览器 (Google Chrome) 最新版离线安装包下载 https://www.iplaysoft.com/tools/chrome/#google_vignette Google Chrome …

socks5代理如何工作?socks5代理可以用来做什么?

socks5代理是一种网络代理服务器&#xff0c;它通常用于改变网络请求的传输方式和地址&#xff0c;从而使得网络请求能够通过代理服务器进行访问。本文将介绍socks5代理的工作原理、优势、使用场景以及如何选择合适的socks5代理。 一、socks5代理的工作原理 socks5代理是一种协…