分享一个计算器

先看效果:
在这里插入图片描述
再看代码(查看更多):

<!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">&#247;</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 === '') return
            if(this.prevOperand !== ''){
                this.calculate();
            }
            this.operation = operation
            this.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>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java分布式微服务1——注册中心(Eureka/Nacos)

文章目录 基础知识注册中心Eureka注册中心与Ribbon负载均衡1、Eureka注册中心2、Eureka的搭建3、Eureka服务注册4、复制服务实例5、拉取服务6、Ribbon负载均衡的流程及Eureka规则调整&#xff1a;7、Ribbon负载均衡饥饿加载 Nacos注册中心1、服务端Nacos安装与启动2、客户端Nac…

管理类联考——逻辑——论证逻辑——汇总篇——目录+提炼

文章目录 一、削弱没有特点的削弱方法关系的削弱必要方法的削弱因果推理的削弱果因推理的削弱概念跳跃的削弱数量比例的削弱比例因果的削弱有效提醒 二、支持方法关系的支持必要方法的支持因果推理的支持果因推理的支持概念跳跃的支持数量比例的支持比例因果的支持 三、假设方法…

IntelliJ IDEA Bookmark使用

1 增加 右键行号栏 2 查看 从favorite这里查看 参考IntelliJ IDEA 小技巧&#xff1a;Bookmark(书签)的使用_bookmark idea 使用_大唐冠军侯的博客-CSDN博客

Windows11右键菜单

刚开始使用Windows11时&#xff0c;新的右键菜单用起来很不习惯。 记录一下修改和恢复Windows11的右键菜单的方法。 1.Win11切换到旧版右键菜单&#xff1a; 方法&#xff1a;WinR打开CMD&#xff0c;运行下面的命令行 添加注册列表重启Windows资源管理器 reg add "HKC…

设备管理系统:提升生产制造企业效率与竞争力的关键

在现代生产制造行业中&#xff0c;设备是企业生产力的核心。有效管理和维护设备对于提高生产效率、降低成本、确保产品质量至关重要。为了满足这些需求&#xff0c;越来越多的生产制造企业开始采用设备管理系统。本文将探讨设备管理系统的重要性以及它对企业的益处。 设备管理…

Qt6之QStackedWidget——Qt仿ToDesk(2)

一、 QStackedWidget概述 QStackedWidget也叫堆栈窗体类&#xff0c;它继承于QFrame&#xff0c;主要与QListWidget等结合使用&#xff0c;实现“一个界面多个页面切换”。 二、QStackedWidget示例 如下图&#xff0c;当点击左边 QListWidget里的菜单时&#xff0c;右边跟随切…

深入学习JVM —— GC垃圾回收机制

前言 前面荔枝已经梳理了有关JVM的体系结构和类加载机制&#xff0c;也详细地介绍了JVM在类加载时的双亲委派模型&#xff0c;而在这篇文章中荔枝将会比较详细地梳理有关JVM学习的另一大重点——GC垃圾回收机制的相关知识&#xff0c;重点了解的比如对象可达性的判断、四种回收…

Prometheus技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》

一、查看可安装的版本 docker search prom/prometheus 二、拉取镜像 docker pull prom/prometheus 三、查看镜像 docker images 四、书写配置文件-以及创建挂载目录 宿主机挂载目录位置&#xff1a; 以及准备对应的挂载目录&#xff1a; /usr/local/docker/promethues/se…

linux之find命令

概览 Linux下find命令在目录结构中搜索文件&#xff0c;并执行指定的操作。Linux下find命令提供了相当多的查找条件&#xff0c;功能很强大。由于find具有强大的功能&#xff0c;所以它的选项也很多&#xff0c;其中大部分选项都值得我们花时间来了解一下。即使系统中含有网络…

ffplay数据结构分析(一)

本文为相关课程的学习记录&#xff0c;相关分析均来源于课程的讲解&#xff0c;主要学习音视频相关的操作&#xff0c;对字幕的处理不做分析 下面我们对ffplay的相关数据结构进行分析&#xff0c;本章主要是对PacketQueue的讲解 struct MyAVPacketList和PacketQueue队列 ffp…

常量池-JVM(十九)

上篇文章说gc日志以及arthas。 Arthas & GC日志-JVM&#xff08;十八&#xff09; 一、常量池 常量池主要放两大类&#xff1a;字面量和符号引用。 字面量就是由字母、数字等构成的字符串或者数值常量。 符号引用主要包含三类常量。 类和接口的全限定名。字段的名称和…

【毕业项目】自主设计HTTP

博客介绍&#xff1a;运用之前学过的各种知识 自己独立做出一个HTTP服务器 自主设计WEB服务器 背景目标描述技术特点项目定位开发环境WWW介绍 网络协议栈介绍网络协议栈整体网络协议栈细节与http相关的重要协议 HTTP背景知识补充特点uri & url & urn网址url HTTP请求和…

python的virtualenv虚拟环境无法激活activate

目录 问题描述&#xff1a; 解决办法&#xff1a; 解决结果&#xff1a; 问题描述&#xff1a; PS D:\pythonProject\pythonProject\DisplayToolLibs\venv\Scripts> .\activate .\activate : 无法加载文件 D:\pythonProject\pythonProject\DisplayToolLibs\venv\Scripts\…

form-create-designer整合element-plus使用方法

最近在使用form-create-designer生成表单的时候遇到了很多问题和各种报错&#xff0c;按照官方文档的方法一步步来做&#xff0c;发现行不通&#xff0c;后来经过不断尝试&#xff0c;终于找到了使用方法&#xff0c;这里做一下总结。 1、安装所需的依赖包 npm install eleme…

Redhat Linux 安装MySQL安装手册

Redhat安装MySQL安装手册 1 下载2 上传服务器、解压并安装3 安装安装过程1&#xff1a;MySQL-shared-5.6.51-1.el7.x86_64.rpm安装过程2&#xff1a;MySQL-shared-compat-5.6.51-1.el7.x86_64.rpm安装过程3&#xff1a;MySQL-server-5.6.51-1.el7.x86_64.rpm安装过程4&#xff…

AWS-自定义ami的S3存取使用

需要提前配置好aws-cli哈 对应的区域 要统一 示例&#xff1a;即AWS-CLI 和 EC2、AMI、S3以上资源均要使用同已区域&#xff0c;以下拿新加坡举例 1.新建自定义AMI 2.查看ami状态 确认是可用状态&#xff0c;才能开始操作 3.aws-cli 开始存入s3 只能使用桶的根目录 开始上…

【golang】工作区与GOPATH

在学习go语言时&#xff0c;我们会从官网下载go语言的二进制包&#xff0c;然后解压并安装到某个目录&#xff0c;最后会配置环境变量&#xff0c;通过输入命令go version来验证是否安装成功。 配置了path环境后&#xff0c;我们还需要再配置3个环境变量&#xff0c;GOROOT、G…

XML(eXtensible Markup Language)

目录 为什么需要XML? 一 XML语法 1.文档声明 2.元素 语法: 3.属性 4.注释 5.CDATA节 二 树结构 三 转义字符 四 DOM4J 1.XML解析技术 2.dom4j介绍 3.dom4j基本使用 XML 指可扩展标记语言&#xff08;eXtensible Markup Language&#xff09;。 XML 被设计用来传…

【新】通达OA前台反序列化漏洞分析

0x01 前言 注&#xff1a;本文仅以安全研究为目的&#xff0c;分享对该漏洞的挖掘过程&#xff0c;文中涉及的所有漏洞均已报送给国家单位&#xff0c;请勿用做非法用途。 通达OA作为历史上出现漏洞较多的OA&#xff0c;在经过多轮的迭代之后已经很少前台的RCE漏洞了。一般来说…

Redis实战案例27-UV统计

1. Redis的HyperLogLog的统计功能 示例&#xff1a; 表明HyperLogLog不管加入重复元素多少次都不会让count&#xff0c;不会计数重复元素&#xff0c;所以适合做UV计数 2. 简单实现UV测试 通过单元测试&#xff0c;向 HyperLogLog 中添加 100 万条数据&#xff0c;看看内存占…