From c7f26c72db58e36007ef7f9eae070d28df50f3de Mon Sep 17 00:00:00 2001 From: JellyBlack Date: Mon, 8 Nov 2021 16:42:55 +0800 Subject: [PATCH 1/2] practice2: zhouxiangyu-2021300119 --- css/iconfont.ttf | Bin 0 -> 1908 bytes css/reset.css | 47 ++++++++++ css/style.css | 126 +++++++++++++++++++++++++ index.html | 57 ++++++++++++ js/events.js | 110 ++++++++++++++++++++++ js/main.js | 236 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 576 insertions(+) create mode 100644 css/iconfont.ttf create mode 100644 css/reset.css create mode 100644 css/style.css create mode 100644 index.html create mode 100644 js/events.js create mode 100644 js/main.js diff --git a/css/iconfont.ttf b/css/iconfont.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2f33db86a098f4c12eee19dacc3ae51b4dc677d5 GIT binary patch literal 1908 zcmd^AOK%%h6h8OPc*gPg5y!!9lVFeYa1c%G#7^wcCRA;jL`YSOnh+s@6dY&#i2RZ> zDGd!(Bt#Gb0gH+SDq_J32_aTg0fdmc03;SjR6>Y{%BB^91sf=v#C&%=7A5@&9P8fu zo$oyEnKSo}i4l=TJ0#KA!r~LB^;d?TBVtovm(DLHlGCHB-#~vA`ZKvowti=2Zxs69 z7~6&NR{pcsGK)mgHuNWpMs_Xy>|1;Ay@io3f>3{uc7Z>|7%W!IOK#rWhwtyu-Q`*? zOIPT9#GBBamF%TD>!hb(KLTB^W-CVLyVD;M$v263pbHDk!HZqmGjx#*-C^Px{_oo|Avy;`GWdYMTN#M<$A;NtY;q!4^jbR8+;s5-iSC zFH@CZ1QSq%1=DcJgo2^4@KvO*LXk*lzv2iu4(@h!IGM_wE+2Pwc)b4bskw2FSCP55 zPwR@DIWf{5adRK{x{ew%eSUA3=JyVEjrK-QJs9u|Xl|ABkHf+JKZ0Q#QHlAYzN1b? zTviSyyg{G8@5Jnw7SsGkpQK)9FEM z>t0FU-EYJ!zw2Osgv`@1)8+`4)F`nSLE{ z1is(KGVsGTcHqmHw6Owy#>Or>MsqgSkg+aqjNE~JV)TNI8FkWoHs<7|JsV5lzp$|k z{GE**6r?*gR>1Gu*hS0CV`GhCEH~RQvZk@7uWsq3T&0htJ$E7*e!_~O;n^~G?1wRG;h~uppr7Mju$9w>&TOXcbtk=RGp4f0>Ae2 nwEg4Ob5^YHo;YmQ|AGY$O%mg{EiyUG%~HWo3P!b* { + height: 9vh; + width: 16.4vw; + margin: 1.5vh 0 0 3vw; + border-radius: 2vw; + background-color: rgb(245, 245, 245); + text-align: center; + line-height: 9vh; + font-size: 26px; +} + +.function>*:hover{ + background-color: rgb(235, 235, 235); +} + +.function>*:active{ + background-color: rgb(205, 205, 205); +} + +/* 功能键 */ + +#clear, +#divide, +#multiply, +#backspace, +#minus, +#plus { + background-color: rgb(233, 240, 255); +} + +#clear:hover, +#divide:hover, +#multiply:hover, +#backspace:hover, +#minus:hover, +#plus:hover { + background-color: rgb(223, 230, 245); +} + +#clear:active, +#divide:active, +#multiply:active, +#backspace:active, +#minus:active, +#plus:active { + background-color: rgb(203, 210, 225); +} + +/* 除清除以外的功能键 */ + +#divide, +#multiply, +#backspace, +#minus, +#plus { + font-size: 36px; +} + +/* 等号键 */ + +#equals { + position: absolute; + right: 0; + top: 77.5vh; + right: 3vw; + height: 19.5vh; + line-height: 19.5vh; + font-size: 36px; + background-color: rgb(59, 131, 119); +} + +#equals:hover{ + background-color: rgb(49, 121, 109); +} + +#equals:active{ + background-color: rgb(29, 101, 89); +} + +/* 图标字体 */ +#sqrt, #backspace { + font-family: "iconfont" !important; + font-size: 26px; + font-style: normal; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +#sqrt { + font-weight: bold; +} + +/* 上标 */ +.function sup{ + position: relative; + /* background-color: transparent; */ + font-size: 16px; + bottom:1.5vh; +} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..d7a7995 --- /dev/null +++ b/index.html @@ -0,0 +1,57 @@ + + + + + + + + H5计算器 + + + + + + + + + +
+ +
+
+
sin
+
+
xy
+
x2
+
π
+
cos
+
C
+
÷
+
×
+
󰆖
+
tan
+
7
+
8
+
9
+
+
lg
+
4
+
5
+
6
+
+
ln
+
1
+
2
+
3
+ +
+
e
+
%
+
0
+
.
+ +
+ + + + diff --git a/js/events.js b/js/events.js new file mode 100644 index 0000000..0600da0 --- /dev/null +++ b/js/events.js @@ -0,0 +1,110 @@ +// 添加按键的响应事件 +window.onload = function() { + document.getElementById("sin").addEventListener('click', function() { + push("sin"); + }); + document.getElementById("sqrt").addEventListener('click', function() { + push("√"); + }); + document.getElementById("pow").addEventListener('click', function() { + push("^"); + }); + document.getElementById("pow2").addEventListener('click', function() { + push("^2"); + }); + document.getElementById("pi").addEventListener('click', function() { + push("π"); + }); + document.getElementById("cos").addEventListener('click', function() { + push("cos"); + }); + document.getElementById("divide").addEventListener('click', function() { + push("÷"); + }); + document.getElementById("multiply").addEventListener('click', function() { + push("×"); + }); + document.getElementById("tan").addEventListener('click', function() { + push("tan"); + }); + document.getElementById("num7").addEventListener('click', function() { + push("7"); + }); + document.getElementById("num8").addEventListener('click', function() { + push("8"); + }); + document.getElementById("num9").addEventListener('click', function() { + push("9"); + }); + document.getElementById("minus").addEventListener('click', function() { + push("-"); + }); + document.getElementById("lg").addEventListener('click', function() { + push("lg"); + }); + document.getElementById("num4").addEventListener('click', function() { + push("4"); + }); + document.getElementById("num5").addEventListener('click', function() { + push("5"); + }); + document.getElementById("num6").addEventListener('click', function() { + push("6"); + }); + document.getElementById("plus").addEventListener('click', function() { + push("+"); + }); + document.getElementById("ln").addEventListener('click', function() { + push("ln"); + }); + document.getElementById("num1").addEventListener('click', function() { + push("1"); + }); + document.getElementById("num2").addEventListener('click', function() { + push("2"); + }); + document.getElementById("num3").addEventListener('click', function() { + push("3"); + }); + document.getElementById("e").addEventListener('click', function() { + push("e"); + }); + document.getElementById("percent").addEventListener('click', function() { + push("%"); + }); + document.getElementById("num0").addEventListener('click', function() { + push("0"); + }); + document.getElementById("dot").addEventListener('click', function() { + push("."); + }); + document.getElementById("backspace").addEventListener('click', function() { + var old_text = document.getElementById("text").innerHTML; + // 如果要删除的是函数(sin, ln等)或“Error”,则删除整体 + if (/[a-z]$/.test(old_text)) { + document.getElementById("text").innerHTML = old_text.match(/.*?(?=(Error|sin|cos|tan|lg|ln)$)/)[0]; + } else { + document.getElementById("text").innerHTML = old_text.substring(0, old_text.length - 1); + } + }); + document.getElementById("clear").addEventListener('click', function() { + document.getElementById("text").innerHTML = ""; + }); + document.getElementById("equals").addEventListener('click', function() { + var text = document.getElementById("text").innerHTML; + document.getElementById("text").innerHTML = calc(text); + document.getElementById("text").classList.add("finish"); + }); +} + +function push(str) { + var old_text = document.getElementById("text").innerHTML; + if (old_text == "Error" || /Infinity/.test(old_text)) { + old_text = ""; + } + if (/^([0-9]|π|e|%|\.)$/.test(str) && document.getElementById("text").classList.contains("finish")) { + old_text = ""; + } + document.getElementById("text").classList.remove("finish"); + document.getElementById("text").innerHTML = old_text + str; +} diff --git a/js/main.js b/js/main.js new file mode 100644 index 0000000..2323bd7 --- /dev/null +++ b/js/main.js @@ -0,0 +1,236 @@ +// 计算 +function calc(str) { + /* + 对象格式 + (Root)[ // 要计算的表达式 + (MathObject){ // 不含乘、除运算的式子 + sign: 1 // 符号 + expression: (SymbolArray)[ + (Symbol){ // 一个数字或运算符 + type: "number", + value: "123" + }, + (Symbol){ + type: "operation" + value: "sin" + }, + (Symbol){...}, + (Symbol){...}, + ... + ] + }, + (MathObject){...}, + (MathObject){...}, + ... + ] + */ + try { + // 无内容,返回空字符串 + if (str == "") { + return ""; + } + // 检查表达式语法 + // 百分号后不允许出现数字 + if (/%([0-9]?\.[0-9]?|[0-9]+)/.test(str)) { + throw new Error("Unexpected number after %"); + } + // 不允许出现连续的加号或减号 + if (/[+-]{2}/.test(str)) { + throw new Error("Plus or minux can't appear together."); + } + // 一个数字中不允许出现两个小数点 + if (/\.[0-9]*\./.test(str)) { + throw new Error("Unexpected number."); + } + // 末尾如果有加号或减号,则加一个0 + if (/[+-]$/.test(str)) { + str += "0"; + } + // 构造Root对象 + var root = split(str); + for (var i = 0; i < root.length; i++) { + root[i].expression = buildSymbolArray(root[i].expression); + } + // console.log(root); + var result = 0; // 计算结果 + // 逐个运算SymbolArray表达式的值 + for (var i = 0; i < root.length; i++) { + // 如果符号是一个百分数,需要特别处理 + if (root[i].expression.length == 1 && root[i].expression[0].type == "number" && /([0-9]+|[0-9]*\.[0-9]*)%/.test(root[i].expression[0].value)) { + // 如果该百分数是第一个式子,则正常运算 + if (i != 0) { + // 此处特别处理,比如100+10%=110 + result *= 1 + root[i].sign * parseNumber(root[i].expression[0].value); + } else { + result += root[i].sign * resolveSymbolArray(root[i].expression); + } + } else { + result += root[i].sign * resolveSymbolArray(root[i].expression); + } + } + // console.log(result); + if (isNaN(result)) { + throw new Error("Invalid calculation result."); + } + // 保留11位小数 + return parseFloat(result.toFixed(11)); + } catch (e) { + console.error(e); + return "Error"; + } +} + +// 拆分+、- +function split(str) { + // 如果第一个字符不是正号或负号,则手动加一个正号 + if (str[0] != '+' && str[0] != '-') { + str = '+' + str; + } + var array = new Array(); + var index = 1; + while (index <= str.length) { + if (index == str.length || str[index] == '+' || str[index] == '-') { + array.push({ + sign: str[0] == '+' ? 1 : -1, + expression: str.substring(1, index) + }); + str = str.substring(index, str.length) + var index = 1; + continue; + } + index++; + } + return array; +} + +// 构造SymbolArray +function buildSymbolArray(str) { + var symbolArray = new Array(); + var number_re = /^(([0-9]*\.[0-9]*|[0-9]+)%?|π|e)/; // 匹配数字的正则表达式 + var operation_re = /^(sin|√|\^|cos|÷|×|tan|-|lg|+|ln)/; // 匹配运算符的正则表达式 + while (str.length != 0) { + if (number_re.test(str)) { + var result = str.match(number_re)[0]; + symbolArray.push({ + type: "number", + value: result + }); + str = str.substring(result.length); + } else if (operation_re.test(str)) { + var result = str.match(operation_re)[0]; + symbolArray.push({ + type: "operation", + value: result + }); + str = str.substring(result.length); + } else { + // 错误 + throw new Error("Building symbol array failed."); + } + } + return symbolArray; +} + +// 计算SymbolArray的值 +function resolveSymbolArray(symbolArray) { + // 如数组为空,返回乘法元1 + if (symbolArray.length == 0) { + return 1; + } + // 第一个符号是数字 + if (symbolArray[0].type == "number") { + var value = parseNumber(symbolArray.shift().value); + // 没有第二个符号 + if (symbolArray.length == 0) { + return value; + } + // 第二个符号也是数字,比如2π + if (symbolArray[0].type == "number") { + return value * resolveSymbolArray(symbolArray); + } else { + var operation = symbolArray[0].value; + // 一元运算符 + if (operation == "sin" || operation == "sqrt" || operation == "cos" || operation == "tan" || operation == "lg" || operation == "ln" || operation == "√") { + return value * resolveSymbolArray(symbolArray); + } + // 二元运算符 + else { + symbolArray.shift(); + if (symbolArray.length == 0) { + // 二元运算符后面没有内容,报错 + throw new Error("No number or operation after symbol " + operation); + } + var object = symbolArray[0]; // 二元运算符后面的第一个符号 + if (object.type == "number") { + // 数字和数字运算 + symbolArray.shift(); + var number = parseNumber(object.value); + if (operation == "^") { + return Math.pow(value, number) * resolveSymbolArray(symbolArray); + } else if (operation == "×") { + return value * number * resolveSymbolArray(symbolArray); + } else if (operation == "÷") { + return value / number * resolveSymbolArray(symbolArray); + } + } else { + // 数字和函数运算,如3×sin6 + if (operation == "^") { + return Math.pow(value, resolveSymbolArray(symbolArray)); + } else if (operation == "×") { + return value * resolveSymbolArray(symbolArray); + } else if (operation == "÷") { + return value / resolveSymbolArray(symbolArray); + } + } + } + } + } + // 第一个符号是运算符 + else { + var operation = symbolArray.shift().value; + // 该符号是一元运算符 + if (operation == "sin" || operation == "sqrt" || operation == "cos" || operation == "tan" || operation == "lg" || operation == "ln" || operation == "√") { + // 运算符后面没有内容,报错 + if (symbolArray.length == 0) { + throw new Error("No number or operation after symbol " + operation); + } + if (operation == "sin") { + return Math.sin(resolveSymbolArray(symbolArray)); + } else if (operation == "sqrt") { + return Math.sqrt(resolveSymbolArray(symbolArray)); + } else if (operation == "cos") { + return Math.cos(resolveSymbolArray(symbolArray)); + } else if (operation == "tan") { + return Math.tan(resolveSymbolArray(symbolArray)); + } else if (operation == "lg") { + return Math.log10(resolveSymbolArray(symbolArray)); + } else if (operation == "ln") { + return Math.log(resolveSymbolArray(symbolArray)); + } else if (operation == "√") { + return Math.sqrt(resolveSymbolArray(symbolArray)); + } + } + // 该符号不是一元运算符,报错 + else { + throw new Error("The first operation number is missing around " + operation); + } + } +} + +// 转换数字 +function parseNumber(str) { + if (str == "e") { + return Math.E; + } + if (str == "π") { + return Math.PI; + } + var number = parseFloat(str); + if (/%$/.test(str)) { + number *= 0.01; + } + if (isNaN(number)) { + throw new Error("Cannot parse number " + str); + } + return number; +} -- Gitee From 5077e15af83a32647b01399b334e15d93f1350ac Mon Sep 17 00:00:00 2001 From: JellyBlack Date: Mon, 8 Nov 2021 18:25:55 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=EF=BC=88=E5=91=A8=E7=BF=94=E5=AE=87=202021?= =?UTF-8?q?300119=EF=BC=89=E4=BF=AE=E6=94=B9=E5=AD=97=E4=BD=93=E9=A2=9C?= =?UTF-8?q?=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/style.css | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/css/style.css b/css/style.css index 921e869..c0b94cd 100644 --- a/css/style.css +++ b/css/style.css @@ -1,7 +1,7 @@ @font-face { font-family: 'iconfont'; src: url('iconfont.ttf?t=1636334307125') format('truetype'); - } +} .display { position: relative; @@ -36,14 +36,28 @@ font-size: 26px; } -.function>*:hover{ +.function>*:hover { background-color: rgb(235, 235, 235); } -.function>*:active{ +.function>*:active { background-color: rgb(205, 205, 205); } +#sin, +#sqrt, +#pow, +#pow2, +#pi, +#cos, +#tan, +#lg, +#ln, +#e { + color: rgb(99, 99, 99); +} + + /* 功能键 */ #clear, @@ -53,6 +67,7 @@ #minus, #plus { background-color: rgb(233, 240, 255); + color: rgb(79, 118, 239); } #clear:hover, @@ -73,6 +88,7 @@ background-color: rgb(203, 210, 225); } + /* 除清除以外的功能键 */ #divide, @@ -83,6 +99,7 @@ font-size: 36px; } + /* 等号键 */ #equals { @@ -94,18 +111,22 @@ line-height: 19.5vh; font-size: 36px; background-color: rgb(59, 131, 119); + color: rgb(253, 253, 253); } -#equals:hover{ +#equals:hover { background-color: rgb(49, 121, 109); } -#equals:active{ +#equals:active { background-color: rgb(29, 101, 89); } + /* 图标字体 */ -#sqrt, #backspace { + +#sqrt, +#backspace { font-family: "iconfont" !important; font-size: 26px; font-style: normal; @@ -117,10 +138,12 @@ font-weight: bold; } + /* 上标 */ -.function sup{ + +.function sup { position: relative; /* background-color: transparent; */ font-size: 16px; - bottom:1.5vh; + bottom: 1.5vh; } \ No newline at end of file -- Gitee