分享一个计算器
先看效果:

再看代码(查看更多):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>计算器</title><style>* {box-sizing: border-box;}body {height: 100vh;display: flex;justify-content: center;align-items: center;font-size: 10px;background: #232323;}@media (max-width: 576px) {body {height: 100h;}}.calc {width: 50em;aspect-ratio: 1/1.5;margin: 2em;background: #232323;background: #CED4CA;background: #EBECE9;padding: 4em;border-radius: 1em;display: flex;flex-direction: column;gap: 2em;box-shadow: rgba(0, 0, 0, 0.15) 0.3em 0.3em 0.8em 0px inset, rgba(0, 0, 0, 0.15) -0.3em 0em 0.8em 0em inset, rgba(0, 0, 0, 0.25) 0.3em 0.3em 0.8em 0px;}@media (max-width: 576px) {.calc {padding: 2.5em;}}.calc .result {height: 12em;background: pink;width: 100%;background: linear-gradient(-30deg, rgba(34, 33, 38, 0.1), rgba(34, 33, 38, 0), rgba(34, 33, 38, 0.1)) 100% 0%/100% 100%, #DBE7E5;box-shadow: rgba(0, 0, 0, 0.2) 0.3em 0.3em 0.6em 0px inset, rgba(0, 0, 0, 0.25) -3px -3px 0.6em 0.1em inset, rgba(0, 0, 0, 0.25) 0px 0em 1.2em 0px inset, rgba(0, 0, 0, 0.25) 0px 0.3em 0.2em 0px inset, rgba(255, 255, 255, 0.85) 0px 0.3em 0.2em 0px;background-repeat: no-repeat;padding: 2em;}@media (max-width: 576px) {.calc .result {height: 10em;}}.calc .result .result__inner {text-shadow: 0.15em 0.15em rgba(0, 0, 0, 0.25);display: flex;justify-content: flex-end;align-items: flex-end;color: #2A3027;height: 100%;font-family: "PT Mono", monospace;display: flex;flex-direction: column;justify-content: space-evenly;}.calc .result .result__inner .prev-operand {font-size: 2em;}.calc .result .result__inner .current-operand {font-size: 4em;font-size: clamp(1.25rem, 0.5368rem + 3.17vw, 2.5rem );font-size: clamp(1.375rem, 0.7338rem + 2.85vw, 2.5rem );font-size: clamp(1.5625rem, 1.027rem + 2.38vw, 2.5rem );}.calc .keys {width: 100%;flex-grow: 2;}.calc .keys__inner {height: 100%;gap: 1.5em;}.calc .key {color: rgba(0, 0, 0, 0.7);border: unset;box-shadow: rgba(0, 0, 0, 0.15) 0.03em 0.03em 0.1em 0px, rgba(0, 0, 0, 0.15) 0.01em 0.01em 0.1em 0px, rgba(255, 255, 255, 0.55) 0em 0em 0.5em 10px inset;font-family: "Rubik", sans-serif;font-size: 4em;font-size: clamp(1rem, 0.3228rem + 3.01vw, 2.1875rem );background: #fff;background: #EBECE9;background-repeat: no-repeat;display: flex;justify-content: center;align-items: center;border-radius: 0.1em;transition: all 0.25s ease;}.calc .key__row {height: 100%;display: grid;width: 100%;grid-template-columns: repeat(4, 1fr);grid-template-rows: repeat(5, 1fr);gap: 1.5em;}@media (max-width: 576px) {.calc .key__row {gap: 0.8em;}}@media (max-width: 576px) {.calc .key {box-shadow: rgba(0, 0, 0, 0.15) 0.03em 0.03em 0.1em 0px, rgba(0, 0, 0, 0.15) 0.01em 0.01em 0.1em 0px, rgba(255, 255, 255, 0.25) 0em 0em 0.5em 10px inset;}}.calc .key:hover {box-shadow: rgba(0, 0, 0, 0.05) 0.03em 0.03em 0.1em 0px, rgba(0, 0, 0, 0.05) 0.01em 0.01em 0.1em 0px, rgba(255, 255, 255, 0.55) 0em 0em 0.5em 10px inset;}.calc .key[data-number] {font-size: clamp(1.5625rem, 1.027rem + 2.38vw, 2.5rem );}.calc .key:nth-of-type(1) {background-color: #C34F61;box-shadow: unset;box-shadow: rgba(0, 0, 0, 0.45) 0.03em 0.03em 0.1em 0px, rgba(0, 0, 0, 0.25) 0.01em 0.01em 0.1em 0px, rgba(225, 167, 176, 0.25) 0em 0em 0.5em 10px inset, rgba(0, 0, 0, 0.15) 0.03em 0.03em 0.1em 0px inset;color: #fff;}.calc .key:nth-of-type(1):hover {box-shadow: rgba(0, 0, 0, 0.15) 0.03em 0.03em 0.1em 0px, rgba(0, 0, 0, 0.05) 0.01em 0.01em 0.1em 0px, rgba(225, 167, 176, 0.25) 0em 0em 0.5em 10px inset;}.calc .key:nth-of-type(16) {grid-row: 4/6;grid-column: 4/4;}</style>
</head>
<body>
<div class="calc"><div class="result"><div class="result__inner"><div data-prev-operand class="prev-operand"></div><div data-current-operand class="current-operand"></div></div></div><div class="keys"><div class="keys__inner"><div class="key__row"><button data-clear class="key">AC</button><button data-operator="**" class="key">x<sup>2</sup></button><button data-operator="/" class="key">÷</button><button data-operator="*" class="key">X</button><button data-number class="key">7</button><button data-number class="key">8</button><button data-number class="key">9</button><button data-operator="-" class="key">-</button><button data-number class="key">4</button><button data-number class="key">5</button><button data-number class="key">6</button><button data-operator="+" class="key">+</button><button data-number class="key">1</button><button data-number class="key">2</button><button data-number class="key">3</button><button data-equals class="key">=</button><button data-number class="key">0</button><button data-number class="key">.</button><button data-delete class="key">DEL</button></div></div></div>
</div>
</body>
<script>class Calculator{constructor(prevOperandText, currentOperandText){this.prevOperandText = prevOperandText;this.currentOperandText = currentOperandText;this.clear();}clear(){this.prevOperand = ''this.currentOperand = ''this.operation = undefined;}delete(){this.currentOperand = this.currentOperand.toString().slice(0,-1);}appendNumber(num){if(num === '.' && this.currentOperand.includes('.')) return;this.currentOperand = this.currentOperand.toString() + num.toString();}selectOperation(operation){if(this.currentOperand === '') returnif(this.prevOperand !== ''){this.calculate();}this.operation = operationthis.prevOperand = this.currentOperand;this.currentOperand = ''}calculate(){let calculation ;const prev = parseFloat(this.prevOperand)const current = parseFloat(this.currentOperand)if(isNaN(prev) || isNaN(current)) return;switch(this.operation){case '+':calculation = prev + current;break;case '-':calculation = prev - current;break;case '*':calculation = prev * current;break;case '÷':calculation = prev / current;break;case '/':calculation = prev / current;break;case '**':calculation = prev ** current;break;case '^':calculation = prev ** current;break;default:return;}if(calculation.toString().length > 12 && calculation.toString().includes('.')){this.currentOperand = calculation.toFixed(5);} else {this.currentOperand = calculation;}this.operation = undefined;this.prevOperand = '';}updateDisplayNumber(num){//从字符串转换为数字const stringNum = num.toString();const integerDigits = parseFloat(stringNum.split('.')[0]);const decimalDigits = stringNum.split('.')[1];let integerDisplay;if(isNaN(integerDigits)){integerDisplay = '';}else{integerDisplay = integerDigits.toLocaleString('en', {maximumFractionDigits: 0});}if(decimalDigits != null){return `${integerDisplay}.${decimalDigits}`;} else{return integerDisplay;}}updateDisplay(){this.currentOperandText.innerText = this.updateDisplayNumber(this.currentOperand);let operation;if(this.operation === "**"){operation = "^";} else {operation = this.operation;}if(this.operation != null){this.prevOperandText.innerText =`${this.updateDisplayNumber(this.prevOperand)} ${operation}`;} else {this.prevOperandText.innerText = '';}}}const operatorKeys = document.querySelectorAll('.key[data-operator]');const numberKeys = document.querySelectorAll('.key[data-number]');const equalButton = document.querySelector('.key[data-equals]')const prevOperandText = document.querySelector('[data-prev-operand]')const currentOperandText = document.querySelector('[data-current-operand]')const clear = document.querySelector('.key[data-clear')const deleteKey = document.querySelector('.key[data-delete')const calculator = new Calculator(prevOperandText,currentOperandText);clear.addEventListener('click', ()=>{calculator.clear();calculator.updateDisplay();})deleteKey.addEventListener('click', ()=>{calculator.delete();calculator.updateDisplay();})numberKeys.forEach(key => {key.addEventListener('click', ()=>{calculator.appendNumber(key.innerText)calculator.updateDisplay()})})operatorKeys.forEach(key => {key.addEventListener('click', ()=>{calculator.selectOperation(key.dataset.operator)calculator.updateDisplay()})})equalButton.addEventListener('click', ()=>{calculator.calculate();calculator.updateDisplay();})document.addEventListener("keydown", (e) => {let numKeys = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "."];let operatorKeys = ["+", "-", "*", "/", "^"];if(numKeys.includes(e.key)){calculator.appendNumber(e.key)calculator.updateDisplay()}if(e.key == "Enter"){calculator.calculate();calculator.updateDisplay();}if(e.key == "Backspace" || e.key == "Delete") {calculator.delete();calculator.updateDisplay();}if(e.key == "Escape"){calculator.clear();calculator.updateDisplay();}if(operatorKeys.includes(e.key)){calculator.selectOperation(e.key)calculator.updateDisplay()}});
</script>
</html>
相关文章:
分享一个计算器
先看效果: 再看代码(查看更多): <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>计算器</title><style>* {box-sizing: border-box;}body…...
Android 13 Launcher——长按图标弹窗背景变暗
目录 一.背景 二.修改代码 一.背景 客户定制需要长按图标弹窗让其背景变暗,所以需要进行定制,如下是定制流程,本篇是接上篇https://gonglipeng.blog.csdn.net/article/details/132171100 的内容 二.修改代码 主要代码逻辑在ArrowPopup中的reorderAndShow方法和closeCom…...
Elasticsearch概述和DSL查询总结
目录 Elasticsearch概述 1. 什么是Elasticsearch 2. 作用 3. 特点 DSL(Domain Specifit Language)特定领域语言: 概念和作用 查询代码总结 最后附项目准备 1.创建搜索工程(maven工程) 2.配置文件 application…...
扩展卡尔曼滤波器代码
文章目录 前言问题状态向量和观测向量加性噪声的形式状态方程及求导观测方程及求导状态初始化过程噪声和观测噪声卡尔曼滤波过程code 前言 卡尔曼滤波器在1960年被卡尔曼发明之后,被广泛应用在动态系统预测。在自动驾驶、机器人、AR领域等应用广泛。卡尔曼滤波器使…...
9:00开始面试,9:08就出来了,这问题问的实在是····
外包工作3年,今年裸辞跳槽,很幸运的是找到了下家,不过 自从加入到这家公司,每天不是在加班就是在加班的路上,薪资倒是给的不少,所以我也就忍了。没想到6月一纸通知,所有人都不许加班࿰…...
揭秘:5个美国程序员与日本程序员的差异
大家好,这里是程序员晚枫。想了解更多精彩内容,快来关注程序员晚枫 今天以美国和日本程序员为例,给大家分享一下国外程序员的生活。 以下是五个美国程序员和日本程序员的的区别: 工作方式:美国程序员通常更注重自由和…...
Springboot实现简单JWT登录鉴权
登录为啥需要鉴权? 登录需要鉴权是为了保护系统的安全性和用户的隐私。在一个 Web 应用中,用户需要提供一定的身份信息(例如用户名和密码)进行登录,登录后系统会为用户生成一个身份令牌(例如 JWT Token&am…...
C++设计模式创建型之工厂模式整理
一、工厂模式分类 工厂模式属于创建型模式,一般可以细分为简单工厂模式、工厂模式和抽象工厂模式。每种都有不同的特色和应用场景。 二、工厂模式详情 1、简单工厂模式 1)概述 简单工厂模式相对来说,在四人组写的《设计模式------可复用面…...
前端安全XSS和CSRF讲解
文章目录 XSSXSS攻击原理常见的攻击方式预防措施 CSRFCSRF攻击原理常见攻击情景预防措施: CSRF和XSS的区别 XSS 全称Cross Site Scripting,名为跨站脚本攻击。为啥不是单词第一个字母组合CSS,大概率与样式名称css进行区分。 XSS攻击原理 不…...
本地化部署自建类ChatGPT服务远程访问
本地化部署自建类ChatGPT服务远程访问 文章目录 本地化部署自建类ChatGPT服务远程访问前言系统环境1. 安装Text generation web UI2.安装依赖3. 安装语言模型4. 启动5. 安装cpolar 内网穿透6. 创建公网地址7. 公网访问8. 固定公网地址 🍀小结🍀 前言 Te…...
一、Webpack相关(包括webpack-dev-server用以热更新和html-webpack-plugin)
概念与功能: webpack是前端项目工程化的具体解决方案。它提供了友好的前端模块化开发支持,以及代码压缩混淆、处理浏览器端JavaScript的兼容性、性能优化等强大的功能。 快速上手:隔行变色 -S实际是--save的简写,表示安装的第三方…...
安全防御(3)
1.总结当堂NAT与双机热备原理,形成思维导图 2.完成课堂nat与双机热备试验 引用IDS是指入侵检测系统,它可以在网络中检测和防御入侵行为。IDS的签名是指根据已知入侵行为的特征制定的规则,用于检测和警告可能存在的入侵行为。签名过滤器可以根…...
AR远程专家指导在汽车改装上的应用有哪些?
随着科技的不断发展,AR增强现实技术逐渐走进了我们的生活。加上商贸国际化,远程协同纵深到制造生产的更多环节,研发协同、工艺优化等场景复杂、跨层级、需要频繁沟通确认的流程正通过AR应用实现全面远程化的过渡,在汽车行业&#…...
css-3:什么是响应式设计?响应式的原理是什么?如何做?
1、响应式设计是什么? 响应式网站设计(Responsive WEB desgin)是一个网络页面设计布局,页面的设计与开发应当根据用户行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的相应和调整。 描述响应式…...
Armstrong数,n位数等于其各位数的n次方之和。
//Armstrong数具有以下特征:一个n位数等于其各位数的n次方之和。 //例如:1531^35^33^3 16341^46^43^44^4 #include<stdio.h> #include<math.h> //实在不知道的暴力求解方法 int main() {//Armstrong数具有以下特征:一个…...
blender的下载安装和配置中文环境
引言 在3D建模和动画设计领域,Blender 作为一款强大且免费的开源软件,一直以优秀的性能和对众多技术的支持赢得了大批用户的喜爱。然而,对于刚接触这款软件的用户而言,其安装和配置过程可能会带来一定困扰,尤其是在设…...
MyCat配置rule.xml、server.xml讲解
1. rule.xml分片规则配置文件 rule.xml中配置的主要就是拆分表的规则,rule.xml中主要包含两类标签 tableRule 和Function。 tableRule标签里面主要配置我们的分片规则,Function里面涉及的是分片规则里面所涉及的java类,都是在function中配置…...
Linux项目部署
目录 一JAVAWeb环境的部署【安装JDK,MySQL数据库,Tomcat】 二.手工部署SpringBoot项目(写的最好的) 1.在IDEA中开发SpringBoot项目并打成jar包--点击右侧的Maven执行package命令 2.将jar包上传到Linux服务器 3.执行以下命令&a…...
案例:Docker 镜像的创建及使用(commit与dockerfile方式)
文章目录 1、commit方式创建镜像1.1、前期准备1.2、制成镜像1.3、启动镜像1.3.1、启动镜像启动nginx1.3.2、一个命令直接全部启动1.3.3、两种方式区别 1.4、commit创建镜像方式的本质 2、Dockerfile的使用2.1、Dockerfile指令2.2、nginx镜像制作案例2.3、查看构建历史ÿ…...
QGIS二次开发三:显示Shapefile
Shapefile 为 OGR 所支持的最重要的数据格式之一,自然可以被 QGIS 加载。那么该如何显示Shapefile呢? 一、先上代码 #include <qgsapplication.h> #include <qgsproviderregistry.h> #include <qgsmapcanvas.h> #include <qgsvec…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
