其他分享
首页 > 其他分享> > 计算器(html+css+js)

计算器(html+css+js)

作者:互联网

文章目录

计算器

先上个效果图 :
(是不是有点眼熟?没错就是win10上的计算器)

原版的:
在这里插入图片描述
我的:
在这里插入图片描述

可以看出,还是有不少区别的,不仅仅是样式上,还有功能上。
(实在是懒得调了,功能的话有点小复杂就少些了几个…)

计算器的操作(运算)逻辑:

  1. 直接按数字、小数点、正负切换、等号、运算符……;
  2. 先按数字,再按小数点、正负切换、运算符、等号……;
  3. 先按数字,再按运算符,再按正负切换,再按等号;例如:1+(-1)=0
  4. 先按数字,再按运算符,再按等号;例如:1+=1 -> 1+1=2
  5. 先按数字,再按运算符,再按数字,再按等号;例如:1+2=3
  6. 先按数字,再按运算符,再按数字,再按等号,再按数字……;
    1. 先按数字,再按运算符,再按数字,再按等号,再按数字,再按运算符,再按数字,再按等号;例如:1+2=3 5+6=11
    2. 先按数字,再按运算符,再按数字,再按等号,再按运算符,再按等号;


    这东西不知道怎样去描述……所以只罗列了一部分情境……
    (总的来说,现在看到的版本,已经是更新过(修复bug)数次后的成品。)

1. html

html:

<!DOCTYPE html>
<!-- 此处省略一部分标签 -->
<body>
	<div class="body">
        <!-- 计算器的头部 -->
        <div class="top">
            <!-- 1.顶部栏 -->
            <span class="title">计算器</span>
            <p>
                <!-- 关闭计算器(页面) -->
                <span class="close" onclick="window.close()">&#10005;</span>
            </p>
            <!-- 2.内容栏 -->
            <p>
                <!-- 用作显示数字及结果的区域 -->
                <span id="show" class="show-view">0</span>
            </p>
        </div>
        <!-- 计算器的按钮 -->
        <div class="content">
            <!--  第一行   +    -    *    /   -->
            <p>
                <span id="+" class="util symbol">+</span>
                <span id="-" class="util symbol">-</span>
                <span id="*" class="util symbol">*</span>
                <span id="/" class="util symbol">/</span>
            </p>
            <!--  第二行   7    8    9    %   -->
            <p>
                <span id="7" class="number">7</span>
                <span id="8" class="number">8</span>
                <span id="9" class="number">9</span>
                <span id="%" class="util symbol">%</span>
            </p>
            <!--  第三行   4    5    6  <[X]  -->
            <p>
                <span id="4" class="number">4</span>
                <span id="5" class="number">5</span>
                <span id="6" class="number">6</span>
                <span id="Backspace" class="util">➨</span>
            </p>
            <!--  第四行   1    2    3    C   -->
            <p>
                <span id="1" class="number">1</span>
                <span id="2" class="number">2</span>
                <span id="3" class="number">3</span>
                <span id="Escape" class="util">C</span>
            </p>
            <!--  第五行  +/-   0    .    =   -->
            <p>
                <span id="change">+/-</span>
                <span id="0" class="number">0</span>
                <span id="point">.</span>
                <span id="result">=</span>
            </p>
        </div>
    </div>
</body>

加个说明:(关于span标签(按钮)的属性)

  1. id
    与之后的JavaScript中的keydown(按下键)/keyup(松开键)监听事件捕获到的key值相对应
  2. class
    number:表示该标签是数字按钮;通过类选择器添加css样式,以及后续的相关事件
    util:表示该标签是工具按钮;同上。
    symbol:表示该标签是运算符按钮;没有相关的css样式,但是有相应的onclick事件

2. css

css:

<style>
        p,
        body {
            margin: 0px;					/*去掉默认的margin值*/
        }
        
        /*计算器整体样式*/
        .body {
            width: 300px;
            height: 404px;
            background-color: rgb(240, 240, 240);
            font-size: 16px;
            color: white;
            border: 1px solid black;
            box-shadow: 2px 2px 10px gray;	/*盒子阴影 有立体感*/
            margin: 20px 0 0 20px;
        }
        
        .top {
            height: 100px;
            position: relative;				/*作为有绝对定位的子元素的参照物*/
        }
        /****************** 头部 ******************/
        
        /*计算器顶栏样式*/
        .top p:nth-of-type(1) {
            height: 30px;
            line-height: 30px;
            text-align: center;				
            opacity: 0;						/*透明度为0 即完全透明 隐藏内容*/
            transition: all 0.5s;
            user-select: none;
            color: gray;
        }
        
        /*当鼠标悬停在计算器顶栏上时 透明度设为1 即显示内容*/
        .top p:nth-of-type(1):hover {
            opacity: 1;
        }
        
        /*计算器标题样式*/
        .top .title {
            position: absolute;
            width: 100px;
            left: 10px;
            top: 3px;
            color: gray;
            user-select: none;
        }
        
        /*关闭按钮的样式*/
        .top .close {
            position: absolute;
            right: 0;
            width: 40px;
            transition: all 0.5s;
        }
        
        /*当鼠标悬停在关闭按钮上时*/
        .top .close:hover {
            background-color: red;
            color: white;
            cursor: default;
        }
        /***************** 显示 *******************/
        
        .top p:nth-of-type(2) {
            font-size: 40px;			/*字体大小*/
            text-align: right;			/*字体对齐方式设置为靠右显示*/
            line-height: 70px;			/*行高*/
            height: 70px;				/*元素高度*/
            color: black;				/*字体颜色*/
        }
        
        .top .show-view {
            display: block;				/*将默认的行元素设置为块元素*/
            width: 95%;					/*元素宽度*/
            margin: 0 auto;				/*水平居中显示*/
            overflow: hidden;			/*超出的部分隐藏*/
        }
        /***************** 按钮-内容 *******************/
        
        /*每一行的样式*/
        .content p {
            height: 60px;				/*元素高度*/
            font-size: 0px;				/*父类元素设置字体大小为0时可以去除掉子类元素(行内块元素)间的间隙*/
            text-align: center;			/*水平居中*/
        }
        
        /*每一行中的每一个按钮的样式*/
        .content p span {
            background-color: white;    /*背景色*/
            color: black;               /*字体颜色*/
            display: inline-block;      /*转换成行内块元素:可以设置宽高并且能在同一行显示*/
            font-size: 20px;			/*字体大小*/
            width: 72px;				/*元素宽度*/
            height: 58px;				/*元素高度*/
            line-height: 58px;			/*行高 当行高与元素高度相同时,文字会垂直居中*/
            transition: all 0.2s;		/*过渡效果*/
            cursor: default;			/*鼠标样式设置为默认的指针样式*/
            border: 1px solid rgb(218, 218, 218);	/*边框线*/
            user-select: none;			/*设置为none后无法选中文本内容  就是去除选中后的蓝色背景色*/
        }
        
        /*当鼠标悬停在按钮上时 添加一个背景色 做一个悬停效果*/
        .content p span:hover {
            background-color: rgb(190, 190, 190);
        }
        
        /*给所有的数字按钮的字体加粗*/
        .content .number {
            font-weight: bold;
        }
        
        /*=号按钮 添加背景色*/ 
        .content #result {
            background-color: rgb(116, 181, 235);
        }
        
        /*=号按钮 鼠标悬浮时加深背景色并添加一个过渡效果*/
        .content #result:hover {
            background-color: rgb(52, 141, 214);
            transition: all 0.2s;
        }
        
        /*单独给退格键添加的样式:使其内容顺时针旋转180°*/
        .content #Backspace {
            transform: rotate(180deg);
        }
        
        /*给所有的工具按钮添加一个背景色*/
        .content .util {
            background-color: rgb(235, 235, 235);
        }
    </style>

3. js

js:(这里使用了jQuery)

<script src="../js/jquery-3.1.1.js"></script>
<script>
	/*获取需要操作及处理的元素对象(因为使用的是jQuery所以获取的都是jQuery对象)*/
	let viewNum = $("#show"); 		 //jQuery对象--显示数字
    let pointBtn = $("#point"); 	 //jQuery对象--小数点按钮
    let changeBtn = $("#change") 	 //jQuery对象--切换数字正负按钮
    let resultBtn = $("#result"); 	 //jQuery对象--计算结果等号按钮
    let deleteBtn = $("#Backspace"); //jQuery对象--撤销退格键按钮
    let clearBtn = $("#Escape"); 	 //jQuery对象--清空按钮
    let numberBtn = $(".number");	 //jQuery对象--数字按钮
    let symbolBtn = $(".symbol"); 	 //jQuery对象--运算符按钮
    
    /*有了按钮对象,就会有相应的点击事件,不过还需要定义一些需要使用的变量*/
    let number1 = 0; 		//数字1 (内部做计算的数字1)
    let number2 = 0; 		//数字2 (内部做计算的数字2)
    let numFactory = ""; 	//数字工厂  (介于内部数字和显示数字之间  对数字进行处理)
    let mos = ""; 			//运算符号(Mathematical operation symbol)  (+ - * / %)
    let hasResult = false; 	//是否存在计算结果 (根据不同的情境 做不同的处理)
    let hasMos = false; 	//是否存在运算符 (根据不同的情境 做不同的处理)
    /*到此准备工作才算完成!*/
</script>

但是在实际过程中,不管是上面写的还是下面写的,都是写的过程中想到可能需要某个东西,才会有这个东西,然后才会去写。
(备注:后面的script都是接着上面的,放在同一个script标签中。)

数字按钮的点击事件

<script>//复制的时候将内容放在同一个script标签中!!!!!!
    /*数字键*/
    numberBtn.click(function() {
        let number = $(this).text();//获取当前触发该事件的对象的文本内容 即数字
        //对按下的数字进行处理
        if (viewNum.text() == number && number == "0") { //当显示的数字为0,且按下的数字也为0时 避免显示多个0
            //多重条件是为了排除某一种情况,并且需要对这种情况进行处理
            numFactory = "0";//就是说,只要当前显示的数字为0,不论你按多少个0,就显示一个0
        } else {//否则按啥数字显示啥,数字加工厂就加工啥
            if (numFactory == "0") {//数字加工厂的数字为0 说明当前显示的数字为0
                numFactory = "";//初始化加工厂 避免数字0开头
            }
            numFactory += number;//字符串的拼接
            viewNum.text(numFactory);//显示数字
        }
    });
</script>

运算符按钮的点击事件

<script>//复制的时候将内容放在同一个script标签中!!!!!!
	/*运算符键*/
	symbolBtn.click(function() {
        //判断是否存在计算方式,如果存在,就先做上一次的计算,然后再设定下一次的计算方式
        if ("" != mos) {//如果运算符不为空时 
            if ("" == numFactory) { //数字工厂为空时
            	//操作流程:数字 运算符 数字 等号 运算符 这种情境时
                hasResult = false;//保证后续操作正常执行:1.运算符 等号 操作;2.运算符 数字
            } else {//数字加工厂不为空 说明存在number1
                if (hasResult && !hasMos) {//当有计算结果 并且 不存在运算符时(hasMos=false)
                	//操作流程:数字 运算符 数字 等号 数字 运算符
                    number1 = parseFloat(numFactory);
                    viewNum.text(numFactory);
                } else {//说明存在number1
                	//操作流程:数字 运算符 数字 运算符
                    number2 = parseFloat(numFactory);//当前显示的数字作为number2
                    numFactory = result();//
                    viewNum.text(numFactory);
                    hasResult = true;
                }
                numFactory = "";
            }
        } else {
            if ("" == numFactory) { //如果直接按计算方式(就是说显示数字为0且没有做任何操作时)时 直接以0作为number1进行相关的计算
                numFactory = "0"; 
            }
            number1 = parseFloat(numFactory);
            numFactory = "";
        }
        mos = $(this).text();
        hasMos = true;
    });
</script>

等号键的点击事件

<script>//复制的时候将内容放在同一个script标签中!!!!!!
	/*等号键*/
    resultBtn.click(function() { //按下等于号 或者 计算方式 时 设置的是number2的值
        if ("" != mos) { //说明number1存在
            if (hasResult) { //如果计算过,number2的值保留
                if ("" != numFactory) {
                    number2 = parseFloat(numFactory);
                }
                numFactory = result();
                viewNum.text(numFactory);
            } else { //否则没计算过,number2的值就等于当前显示的值
                if ("" == numFactory) {
                    numFactory = viewNum.text();
                }
                number2 = parseFloat(numFactory);
                numFactory = result();
                viewNum.text(numFactory);
                hasResult = true; //只要计算过一次就改为true
            }
            numFactory = "";
            hasMos = false;
        } else { //不存在就什么操作都不做
            if ("" == numFactory) {
                viewNum.text("0");
            } else {
                viewNum.text(numFactory);
            }
        }
    });
	
	/*根据运算符执行相应的操作,即计算结果*/
	function result() {
        switch (mos) {
            case "+":
                number1 = number1 + number2;
                return number1;
            case "-":
                number1 = number1 - number2;
                return number1;
            case "*":
                number1 = number1 * number2;
                return number1;
            case "/":
                number1 = number1 / number2;
                return number1;
            case "%":
                number1 = number1 % number2;//可以看到这里的%号是取余数
                return number1;
        }
    }
</script>

+/-按钮的点击事件

<script>//复制的时候将内容放在同一个script标签中!!!!!!
	/*按下切换正负值按钮后进行的操作及处理*/
    changeBtn.click(function() { //功能:切换当前数字的正负值,或将当前数字取反作为第二个数字
        //判断是否存在计算结果
        if (hasResult) { //有计算结果时 说明存在number1的值
            number1 = number1 * -1;//无论number1的值是正或负,都乘以-1取反
            numFactory = number1;
            viewNum.text(numFactory);
            numFactory = "";//将数字加工厂清空  等待下一个需要加工的数字
        } else { //没计算结果时,但也可能存在number1的值
            if (hasMos) { //有运算符时 说明存在number1的值
                if ("" != numFactory) { //数字加工厂 不为空时 就对该数字进行加工处理
                    if (numFactory.startsWith("-")) {//说明当前的数字是负数
                        numFactory = numFactory.substring(1, numFactory.length);//截取掉'-'号变成正数。
                    } else {//说明是正数
                        numFactory = "-" + numFactory;//加上'-'号变成负数
                    }
                    viewNum.text(numFactory);//将加工后的数字做显示
                } else { //数字加工厂为空时 就以number1的值取反 作为当前需要加工的数字
                    numFactory = "" + number1 * -1;
                    viewNum.text(numFactory);
                }
            } else {//没有运算符时 就不存在number1 但也说明当前操作的数字 就是 加工厂正在处理的数字
                if ("" != numFactory) { //不为空时 才做处理
                    if (numFactory.startsWith("-")) {
                        //说明当前的数字是负数
                        numFactory = numFactory.substring(1, numFactory.length);
                    } else {
                        //说明是正数
                        numFactory = "-" + numFactory;
                    }
                    viewNum.text(numFactory);
                }
            }
        }
    });
</script>

小数点按钮的点击事件

<script>//复制的时候将内容放在同一个script标签中!!!!!!
	/*按下小数点后进行的操作及处理*/
    pointBtn.click(function() {
        if ("" != numFactory) { //当 数字加工厂 不为空时
            //判断内容是否包含“.”
            if (numFactory.indexOf(".") == -1) { //返回值为-1 说明不包含
                numFactory += "."; //拼接一个'.'
                viewNum.text(numFactory); //将 加工后的值 做显示
            }
        } else { //当 数字加工厂 为空时
            numFactory = "0."; //以0为初始值,并拼接上一个小数点
            viewNum.text(numFactory); //将 加工后的值 做显示
        }
    });
</script>

退格键按钮的点击事件

<script>//复制的时候将内容放在同一个script标签中!!!!!!
	/*退格键*/
    deleteBtn.click(function() {
        if (numFactory.length > 0) { //长度不为0的时候才删除
            numFactory = numFactory.substring(0, numFactory.length - 1);
            if ("" == numFactory || numFactory == "-") {
                //长度删到为0的时候恢复初始状态
                viewNum.text("0");
            } else {
                viewNum.text(numFactory);
            }
        }
    });
</script>

清空键按钮的点击事件

<script>//复制的时候将内容放在同一个script标签中!!!!!!
	/*清空键*/
    clearBtn.click(function() {
        numFactory = "";
        mos = "";
        hasResult = false;
        hasMos = false;
        number1 = 0;
        number2 = 0;
        viewNum.text("0");
    });
</script>

鼠标点击事件以及键盘按下事件

<script>
	let button = $(".content p span");//获取所有按钮的jQuery对象
    button.mousedown(function() {//鼠标按下触发的事件
        let btn = $(this);
        if (btn.text() == "=") {
            btn.css("backgroundColor", "rgb(27, 102, 163)");
        } else {
            btn.css("backgroundColor", "rgb(150, 150, 150)");
        }
        btn.css("transition", "all 0.2s");
        btn.mouseup(function() {//鼠标松开触发的事件
            btn.css({
                "backgroundColor": "",
                "transition": ""
            });
        });
    });

    $(window).keydown(function(e) {//键盘按下触发的事件
        button.each(function(index) {
            let btn = $(this);
            if (e.key == btn.text() || e.key == btn[0].id) {//e.key获取的是当前按下的键盘所代表的键值
                btn.click();
                btn.css({
                    "backgroundColor": "rgb(150, 150, 150)",
                    "transition": "all 0.2s"
                });
            }
            if ((e.key == "=" || e.key == "Enter") && btn.text() == "=") {
                btn.click();
                btn.css({
                    "backgroundColor": "rgb(27, 102, 163)",
                    "transition": "all 0.2s"
                });
            }
        });
        $(this).keyup(function(e) {//键盘松开触发的事件
            button.css({
                "backgroundColor": "",
                "transition": ""
            });
        })
    });
</script>

因为本人在写的过程是不断在修改,而计算器不同的操作之间都会有所牵扯,所以实在不好描述。
感兴趣的小伙伴,可以copy下来,自己实操一下,但是其中的原理或者逻辑,就只能看悟性了……
(另:如果发现bug,欢迎补充)

标签:运算符,数字,text,按钮,js,numFactory,html,number1,css
来源: https://blog.csdn.net/weixin_41850612/article/details/111564050