计算器(html+css+js)
作者:互联网
文章目录
计算器
先上个效果图 :
(是不是有点眼熟?没错就是win10上的计算器)
原版的:
我的:
可以看出,还是有不少区别的,不仅仅是样式上,还有功能上。
(实在是懒得调了,功能的话有点小复杂就少些了几个…)
计算器的操作(运算)逻辑:
- 直接按数字、小数点、正负切换、等号、运算符……;
- 先按数字,再按小数点、正负切换、运算符、等号……;
- 先按数字,再按运算符,再按正负切换,再按等号;
例如:1+(-1)=0
- 先按数字,再按运算符,再按等号;
例如:1+=1 -> 1+1=2
- 先按数字,再按运算符,再按数字,再按等号;
例如:1+2=3
- 先按数字,再按运算符,再按数字,再按等号,再按数字……;
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()">✕</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标签(按钮)的属性)
- id
与之后的JavaScript中的keydown(按下键)/keyup(松开键)监听事件捕获到的key值相对应- 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