前言:
既然有这么一个编写计算器的要求,那就让我们开始分析它需要什么,之后再编写它。
基本的外观可以参照电脑上的计算器,有显示屏显示算式和结果,有数字按钮和符号按钮。
(计算器的外观可以通过html编写按钮实现也可以通过使用js实现。由于老师的要求,我编写的计算器的大部分都是用了js来实现。)
既然要编写一个东西,那么这个东西就必须要有他的一些功能。那么显然,计算器的功能就是计算,由于是初级的计算器,我们只需要编写一些简单且基本的功能,加减乘除和等于。
两个文本框,第一个文本框装算式,第二个文本框装结果(第二个文本框里面的值可以转到第一个文本框里面,实现算式的进一步计算)
- <input type="text" class="outbefore" id="shuchukuangbefore" readonly="readonly">
-
- <input type="text" class="outafter" id="shuchukuangafter" readonly="readonly">
(下面是后面进阶计算器功能的补全,为了整体的阅读,我把它调到这里,第一次阅读请跳过)
【
四个另外的按钮,让计算更方便
- <input type="button" value="平方" id="平方">
- <input type="button" value="+/-" id="+/-">
- <input type="button" value="CE" id="CE">
- <input type="button" value="退格" id="退格">
】
分析
我们要将十个数字,加减乘除,小数点以及等于号这十六个功能按钮一一编写是很麻烦的,那么我们就使用js中的for循环来动态创建出来十六个按钮。两个for循环嵌套,外面的for循环创造出四个盒子(div),这四个盒子里面分别生成出四个按钮,再将数组symbol的值分别赋予它们。
代码实现
- //后面我会说为什么是这么个顺序
- var symbol = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "+", "=", "-", ".", "/"];
-
- for (i = 0; i < symbol.length / 4; i++) {
- var div = document.createElement("div");
- for (m = 0; m < symbol.length / 4; m++) {
- var input = document.createElement("input");
- input.type = "button";
- input.value = symbol[i * 4 + m];
- input.id = i * 4 + m;
- // 将四个按钮添加给div
- div.appendChild(input);
- input.onclick = function () {
- // this指的是调用函数的对象,此处指的是input
- // 注意,这里将按钮的值赋给了显示屏中的第一个文本框
- shuchukuangbefore.value += this.value;
- }
- }
- // 将div添加到body里面
- document.body.appendChild(div);
- }
2.2.2.1.等于“=”按钮
分析
很简单的逻辑,只需要将第一个文本框里面的值(包括数字和计算符号)通过计算公式eval加工完后赋予第二个文本框
代码实现
- //抓取id为12的按钮(等于号“=”)
- var results = document.getElementById("12");
- results.onclick = function () {
- var result;
- // 判断程序是否出错,当出错时会出现err错误值
- try {
- result = eval(shuchukuangbefore.value);
- }
- catch (err) {
- result = err;
- }
- shuchukuangbefore.value += "=";
- shuchukuangafter.value = result;
- }
ps.
到这里计算器的最基本的功能已经写完了,其实将一个整体拆分成一个一个小部分后你会觉得其实也没什么难的。好了,下面我们进行计算器的进阶,补全它的一些功能。
由于js的动态生成按钮后不适合再在js里面添加一些按钮功能,那么就直接在html部分添加它们。为了方便阅读,我将它们加到html部分了。
下面我们真正进入js部分的进阶版
2.2.2.2.清零“CE”按钮
分析
简单的字符串赋空值
代码实现
- var clear = document.getElementById("CE");
- clear.onclick = function () {
- shuchukuangbefore.value = "";
- shuchukuangafter.value = "";
- }
2.2.2.3.退格backspace按钮
分析
将显示屏中的第一个文本框的值赋给back字符串,利用字符串的截取实现退格功能(这里还是用了一个小技巧,就是“中间瓶”)
代码实现
- var Backspace = document.getElementById("退格");
- Backspace.onclick = function () {
- var back = shuchukuangbefore.value;
- var Backed = back.substring(0, back.length - 1);
- shuchukuangbefore.value = Backed;
- }
2.2.2.4.平方按钮
分析
利用函数Math.pow()返回平方值(后期可以进行改进,比如N次方按钮)
代码实现
- var pingfang = document.getElementById("平方");
- pingfang.onclick = function () {
- shuchukuangafter.value = Math.pow(shuchukuangbefore.value, 2);
- }
2.2.2.5.+/-按钮
分析
值的简单符号变换。
代码实现
- //让符号变反数,当有shuchukuangafter时对输出结果进行正反输出,当shuchukuangafter没有时对shuchukuagnbefore进行正反输出
- var zhengfan = document.getElementById("+/-");
- zhengfan.onclick = function () {
- if (shuchukuangafter.value != 0)
- shuchukuangafter.value = -shuchukuangafter.value;
- else {
- shuchukuangbefore.value = -shuchukuangbefore.value;
- }
- }
键盘事件就是使用键盘也可以进行计算操作(小键盘)。看起来很难,但只是将鼠标点击事件换成了键盘触击事件。这里涉及到键盘按键键码值keyCode(大家自己了解一下吧,我也不太清楚,一知半解)
2.2.3.1.十个数字,加减乘除和小数点的键盘事件
分析
键盘上的数字和运算符号的键码值是有一定顺序的,这也解释了为什么我前面指定的数组symbol值的顺序那么奇怪,就是为了让这里的for循环能够顺利执行。
for循环将电脑抓取的键码值与前面的16个按钮的value值一一对应并赋给显示屏的第一个文本框
代码实现
- // 定义十个数字和加减乘除和.的键盘事件,此处i是它们的键码值
- for (var i = 96; i <= 111; i++) {
- if (e.keyCode === i) {
- shuchukuangbefore.value += document.getElementById(i - 96).value;
- }
- }
2.2.3.2.Enter计算出最后结果的键盘事件
分析
和前面的等于“=”按钮类似,只是从鼠标点击事件变成了键盘触击事件
代码实现
- if (e.keyCode === 13) {
- try {
- result = eval(shuchukuangbefore.value);
- }
- catch (err) {
- result = err;
- }
- shuchukuangbefore.value += "=";
- shuchukuangafter.value = result;
- }
2.2.3.2.退格backspace键盘事件
分析
和前面的退格backspace按钮类似,只是从鼠标点击事件变成了键盘触击事件
代码实现
- if (e.keyCode === 8) {
- var back = shuchukuangbefore.value;
- var Backed = back.substring(0, back.length - 1);
- shuchukuangbefore.value = Backed;
- }
2.2.3.2.清零按钮shift键盘事件
分析
和前面的清零“CE”按钮类似,只是从鼠标点击事件变成了键盘触击事件
代码实现
- if (e.keyCode === 16) {
- shuchukuangbefore.value = "";
- shuchukuangafter.value = "";
- }
复杂的东西是由简单的东西构成,当你觉得一件事情很难解决,试着拆解它,一部分一部分解决它。这里有一个诀窍,先确定主体再确定枝干最后解决末端细节。
下面是全部代码,里面包含了许多细节修改和bug修复
- <!DOCTYPE html>
- <html lang="en">
-
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>计算器</title>
- <style>
- * {
- margin: 0;
- padding: 0;
- }
-
- body {
- text-align: center;
- background-image: url("https://img.tt98.com/d/2020/2020062917009557/5ef9ab0e0f1fd.jpg");
- background-repeat: no-repeat;
- background-position: center;
- background-size: 100%;
- }
-
- p {
- position: absolute;
- right: 450px;
- }
-
- .shuchukuang {
- width: 290px;
- height: 80px;
- margin: 60px auto 5px auto;
- font-size: 0px;
- }
-
- .shuchukuang input {
- margin: 0;
- border-radius: 30px;
- cursor: not-allowed;
- }
-
- .shuchukuang .outbefore {
- width: 290px;
- height: 30px;
- border: none;
- border-radius: 0;
- font-size: 20px;
- color: #d0d0d1;
- }
-
- .shuchukuang .outafter {
- width: 290px;
- height: 50px;
- border-radius: 0;
- font-size: 45px;
- border: none;
- }
-
- .gongneng {
- font-size: 0;
- }
-
- input {
- width: 70px;
- height: 45px;
- margin: 2px;
- box-shadow: 2px 2px 2px gray;
- background-color: #b490b8;
- border: none;
- border-radius: 25px;
- outline: none;
- cursor: pointer;
- }
-
- input:hover {
- background-color: aqua;
- }
- </style>
- </head>
-
- <body>
- <h1>欢迎使用XXX的计算器</h1>
- <p>---键盘使用也可,shift清零</p>
- <div class="shuchukuang">
- <input type="text" class="outbefore" id="shuchukuangbefore" readonly="readonly">
- <input type="text" class="outafter" id="shuchukuangafter" readonly="readonly">
- </div>
- <div class="gongneng">
- <input type="button" value="平方" id="平方">
- <input type="button" value="+/-" id="+/-">
- <input type="button" value="CE" id="CE">
- <input type="button" value="退格" id="退格">
- </div>
- <script>
- var i, m;
- // 此处更改symbol值的顺序是为了实现键盘事件,因为键码值的顺序连续
- var symbol = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "+", "=", "-", ".", "/"];
- // 外面的for循环动态设置了四个div盒子,分别装有四个不同的按钮
- for (i = 0; i < symbol.length / 4; i++) {
- var div = document.createElement("div");
- // 里面的for循环动态设置了四个不同的按钮
- for (m = 0; m < symbol.length / 4; m++) {
- var input = document.createElement("input");
- input.type = "button";
- input.value = symbol[i * 4 + m];
- input.id = i * 4 + m;
- // 将四个按钮添加给div
- div.appendChild(input);
- input.onclick = function () {
- // this指的是调用函数的对象,此处指的是input
- shuchukuangbefore.value += this.value;
- }
- // 补全因两个input(shuchukuangbefore和shuchukuangafter)导致的加减乘除键盘的修正
- if (input.id == 10 || input.id == 11 || input.id == 13 || input.id == 15) {
- input.onclick = function () {
- // this指的是调用函数的对象,此处指的是input
- if (shuchukuangafter.value != 0) {
- shuchukuangbefore.value = shuchukuangafter.value;
- }
- shuchukuangbefore.value += this.value;
- }
- }
- }
- document.body.appendChild(div);
- }
- // 定义最后输出内容按钮
- var results = document.getElementById("12");
- results.onclick = function () {
- var result;
- // 判断程序是否出错,当出错时会出现err错误值
- try {
- // 这里的if语句和isInteger是为了判断输出框内容是否为小数
- function isInteger(obj) {
- return (obj | 0) === obj
- }
- if (isInteger((eval(shuchukuangbefore.value))) == true) {
- result = eval(shuchukuangbefore.value);
- }
- else {
- result = eval(shuchukuangbefore.value).toFixed(2);
- }
- }
- catch (err) {
- result = err;
- }
- shuchukuangbefore.value += "=";
- shuchukuangafter.value = result;
- }
- // 定义清零CE按钮
- var clear = document.getElementById("CE");
- clear.onclick = function () {
- shuchukuangbefore.value = "";
- shuchukuangafter.value = "";
- }
- // 定义退格backspace按钮
- var Backspace = document.getElementById("退格");
- Backspace.onclick = function () {
- var back = shuchukuangbefore.value;
- var Backed = back.substring(0, back.length - 1);
- shuchukuangbefore.value = Backed;
- }
- // 定义平方按钮
- var pingfang = document.getElementById("平方");
- pingfang.onclick = function () {
- shuchukuangafter.value = Math.pow(shuchukuangbefore.value, 2);
- }
- //定义+/-按钮
- //让符号变反数,当有shuchukuangafter时对输出结果进行正反输出,当shuchukuangafter没有时对shuchukuagnbefore进行正反输出
- var zhengfan = document.getElementById("+/-");
- zhengfan.onclick = function () {
- if (shuchukuangafter.value != 0)
- shuchukuangafter.value = -shuchukuangafter.value;
- else {
- shuchukuangbefore.value = -shuchukuangbefore.value;
- }
- }
- // 定义键盘事件
- document.body.onkeydown = function (e) {
- // 键盘事件:使用键盘时会触发其他按钮点击事件,导致字符多输入情况
- e.preventDefault();
- // 补全因两个input(shuchukuangbefore和shuchukuangafter)导致的加减乘除键盘的修正
- if (e.keyCode == 106 || e.keyCode == 107 || e.keyCode == 109 || e.keyCode == 111) {
- if (shuchukuangafter.value != 0) {
- shuchukuangbefore.value = shuchukuangafter.value;
- // var yuzeliang = e.keyCode;
- // shuchukuangbefore.value += document.getElementById(yuzeliang - 96).value;
- }
- }
- // 定义十个数字和加减乘除和.的键盘事件,此处i是它们的键码值
- for (var i = 96; i <= 111; i++) {
- if (e.keyCode === i) {
- shuchukuangbefore.value += document.getElementById(i - 96).value;
- }
- }
- // 定义enter事件,计算出多少数值
- if (e.keyCode === 13) {
- try {
- function isInteger(obj) {
- return (obj | 0) === obj
- }
- if (isInteger((eval(shuchukuangbefore.value))) == true) {
- result = eval(shuchukuangbefore.value);
- }
- else {
- result = eval(shuchukuangbefore.value).toFixed(2);
- }
- }
- catch (err) {
- result = err;
- }
- shuchukuangbefore.value += "=";
- shuchukuangafter.value = result;
- }
- // 定义退格backspace事件
- if (e.keyCode === 8) {
- var back = shuchukuangbefore.value;
- var Backed = back.substring(0, back.length - 1);
- shuchukuangbefore.value = Backed;
- }
- //定义清零按钮shift
- if (e.keyCode === 16) {
- shuchukuangbefore.value = "";
- shuchukuangafter.value = "";
- }
- }
- </script>
- </body>
-
- </html>
以上为正文所有内容