分享一个计算器

news2024/12/24 21:45:13

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

<!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>

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

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

相关文章

threejs点击模型实现模型边缘高亮的选中效果--更改后提高帧率

先来个效果图 之前写的那个稍微有点问题&#xff0c;帧率只有30&#xff0c;参照官方代码修改后&#xff0c;帧率可以达到50了&#xff0c;在不全屏的状态下&#xff0c;帧率60 1.首先需要导入库 // 用于模型边缘高亮 import { EffectComposer } from "three/examples/js…

React Native 样式布局基础知识

通过此篇笔记能够学习到如下的几个知识点 在 React Native 中使用样式的一些细节了解 React Native 的 Flex 布局概念了解 React Native 的 flex 布局属性React Native 如何添加多样式属性React Native 中绝对布局和相对布局 React Native 中的 Flex 布局概念 1、主轴和交叉…

06-1_Qt 5.9 C++开发指南_对话框与多窗体设计_标准对话框

在一个完整的应用程序设计中&#xff0c;不可避免地会涉及多个窗体、对话框的设计和调用&#xff0c;如何设计和调用这些对话框和窗体是搞清楚一个庞大的应用程序设计的基础。本章将介绍对话框和多窗体设计、调用方式、数据传递等问题&#xff0c;主要包括以下几点。 Qt 提供的…

JavaWeb 速通Cookie

目录 一、关于base标签 1.引入 : 2.介绍 : 3.实例 : 4.细节 : 二、Cookie的引入 1.会话技术 : 1 什么是会话技术&#xff1f; 2 会话技术用于解决什么问题&#xff1f; 2.Cookie介绍 1 Cookie有什么用&#xff1f; 2 Cookie通讯机制 三、Cookie的基本使用 1.创建Cookie…

【数据结构】带你图文结合深入栈和队列,并具体分步实现

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;我们继续来学习初阶数据结构的内容&#xff0c;今天我们要讲的是栈与队列部分的内容&#xff0c;这篇博客先讲栈&#xff0c;队列我们放到下次再讲 好了&#xff0c;废…

看完秒懂:5G技术会给视频监控行业带来怎样的变革?

5G是第五代移动通信技术&#xff0c;能够提供更高的带宽和更快的传输速度&#xff0c;这将为视频技术的发展带来大量机会。随着5G技术的逐步普及与商用&#xff0c;人们将能够享受到更加流畅的高清视频体验&#xff0c;并且5G技术还拥有更低的延迟和更高的网络容量。这些优势不…

(树) 剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 ——【Leetcode每日一题】

❓剑指 Offer 68 - I. 二叉搜索树的最近公共祖先 难度&#xff1a;简单 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科 中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满…

分清性能测试,负载测试,压力测试这三个的区别

做测试一年多来&#xff0c;虽然平时的工作都能很好的完成&#xff0c;但最近突然发现自己在关于测试的整体知识体系上面的了解很是欠缺&#xff0c;所以&#xff0c;在工作之余也做了一些测试方面的知识的补充。不足之处&#xff0c;还请大家多多交流&#xff0c;互相学习。 …

RN 使用react-navigation写可以滚动的横向导航条(expo项目)

装包&#xff1a; yarn add react-navigation/material-top-tabs react-native-tab-view npx expo install react-native-pager-view import React from react import { View, Text, ScrollView, SafeAreaView } from react-native import { Icon } from ../../../../../compo…

ElastAlert通过飞书机器人发送报警通知

前言 公司采用ELK架构搜集业务系统的运行日志&#xff0c;以前开发人员只有在业务出现问题的时候&#xff0c;才会去kibana上进行日志搜索操作&#xff0c;每次都是被用户告知系统出问题了&#xff0c;这简直是被啪啪打脸~ 于是痛定思痛&#xff0c;决定主动出击&#xff0c;…

【刷题笔记8.8】两数之和

LeetCode&#xff08;Hot100&#xff09;&#xff1a;两个数之和 题目描述及示例&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会…

学成在线踩坑

这段时间在做学成在线的过程中&#xff0c;偷懒遇到了一个这个问题&#xff0c;这个问题是直接跑老师的程序出现的&#xff0c;配置文件方面并没有出其他情况&#xff0c;找了半天&#xff0c;没找到错误。最后因为分析可能是MediaFileServiceImpl.java这个代码出了问题&#x…

Spring高手之路12——BeanDefinitionRegistry与BeanDefinition合并解析

文章目录 1. 什么是BeanDefinitionRegistry&#xff1f;2. BeanDefinitionRegistry 的使用2.1 BeanDefinitionRegistry 简单例子2.2 有关ImportBeanDefinitionRegistrar的实现类的例子 3. BeanDefinition的合并3.1 调试验证BeanDefinition的合并3.2 BeanDefinition合并的目的 4…

怎么在JMeter中的实现关联

我们一直用的phpwind这个系统做为演示系统, 如果没有配置好的同学, 请快速配置之后接着往下看哦. phpwind发贴时由于随着登陆用户的改变, verifycode是动态变化的, 因此需要用到关联. LoadRunner的关联函数是reg_save_param, Jmeter的关联则是利用后置处理器来完成. 在需要查…

jpa Page 1 of 0 containing UNKNOWN instances错误关于like问题的解决记录

导致这个问题的原因很多&#xff0c;这里记录一下我碰到的问题和解决方法。 网上有说时 pageNo要从0开始&#xff0c;我的不是这个问题。 在使用springboot jpa时&#xff0c;发现使用 t.ip like %?5% 语句&#xff0c;如果数据库记录的ip is null时&#xff0c;将查询不到该…

【网络】应用层——HTTPS协议

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《网络》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; HTTPS协议 &#x1f349;HTTP的不安全性&#x1f349;认识HTTPS协议&#x1f353;加密解密&#x1f35…

露营,「迷失」在春风里

【潮汐商业评论/原创】 “周末一起去露营吧&#xff1f;”Susan向闺蜜发起邀请。 Susan闺蜜看到后连忙说“去多了感觉没意思&#xff0c;还不如去隔壁城市走走呢&#xff1f;”两人一拍即合&#xff0c;便研究起了攻略。 Susan疑惑&#xff0c;好像露营也没火多久&#xff0…

【Linux】-- 进程间通信

目录 一、进程间通信介绍 二、管道 1.什么是管道&#xff08;pipe&#xff09; 2.重定向和管道 &#xff08;1&#xff09;为什么要有管道的存在 &#xff08;2&#xff09;重定向和管道的区别 3.匿名管道 &#xff08;1&#xff09;匿名管道原理 &#xff08;2&…

springAOP的实例

文章目录 前言一.用户登录权限校验1.1 spring 拦截器1.2 传统的用户登录权限验证1.3 使用拦截器的方式1.4 案例1.5 拦截器实现原理 三.统一异常处理3.1 什么是统一异常处理3.2 具体步骤 四.统⼀数据返回格式4.1 为什么需要统一的数据返回4.2 统一返回数据的格式4.3 统一移除处理…