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

再看代码(查看更多):
<!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…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...
