用JavaScript制作一个计算器,可以进行加、减、乘除、指数、根号、括号运算。
功能上较难实现的是指数与根号运算,但在算法实现上两者其实大同小异。
一种方案是用 ** 直接实现指数运算。
另一种方案较麻烦,也比较锻炼人,则是修改表达式,使之用Math.pow()函数去运算,本次实验中,我使用的也是这种方法。
还需改进的地方:精度问题。
重点掌握eval()
css:
html:table{ background-color: white; height:500px; } td{ height:100px; width:120px; background-color: slategray; color:white; border-collapse: ; text-align:center; font-size:30px; } .left{ text-align:left; } .darkorange{ background-color: darkorange; }
js:<form> <table id="table1"> <tr> <td class="darkorange" colspan="6"> 0 </td> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> <td>*</td> <td>/</td> <td>^</td> </tr> <tr> <td>4</td> <td>5</td> <td>6</td> <td>+</td> <td>-</td> <td> root </td> </tr> <tr> <td>7</td> <td>8</td> <td>9</td> <td>(</td> <td>)</td> <td class="darkorange" rowspan="2">=</td> </tr> <tr> <td class="darkorange" colspan="2">c</td> <td>0</td> <td>.</td> <td>del</td> </tr> </table> </form>
var formula=''; var symbol=0,flag=0,Clear=1,pri=0; var formula2=''; var row=1,col=0; var index=0; for(;row<5;row++){ for(col=0;col<6;col++){ if((col==0||col==3||col==4||col==5)&&row==4) continue; if(row==3&&col==5) continue; document.getElementById("table1").rows[row].cells[col].addEventListener("click",show,false); } } //del document.getElementById("table1").rows[4].cells[3].addEventListener("click",del,false); //= document.getElementById("table1").rows[3].cells[5].addEventListener("click",equal,false); //c document.getElementById("table1").rows[4].cells[0].addEventListener("click",clear,false); //^ document.getElementById("table1").rows[1].cells[5].addEventListener("click",exponent,false); //root document.getElementById("table1").rows[2].cells[5].addEventListener("click",root,false); //right document.getElementById("table1").rows[3].cells[4].addEventListener("click",right,false); //left document.getElementById("table1").rows[3].cells[3].addEventListener("click",left,false); function show(){ //have entered "=" if(flag==1){ if(!isNaN(this.innerHTML)||this.innerHTML=='.'||this.innerHTML=='('||this.innerHTML==')'){ if(this.innerHTML=='0') document.getElementById("table1").rows[0].cells[0].innerHTML="0"; formula=''; formula2=''; flag=0; } } //enter // check the first key if(formula.length==0&&flag==0){ Clear=0; // enter "0" at the begin if(this.innerHTML=='0') formula=''; // if the first key isNaN else{ if( isNaN(this.innerHTML)&&this.innerHTML!='('&&this.innerHTML!=')') formula="0"+this.innerHTML; // if the first key is a number or "()" else formula+=this.innerHTML; document.getElementById("table1").rows[0].cells[0].innerHTML=formula; formula2=formula; } } //not the first key else{ flag=0; // choose one opearation at one time if(isNaN(this.innerHTML)){ var a=formula[formula.length-1]; if((isNaN(a)&&a!='('&&a!=')'&&this.innerHTML!='('&&this.innerHTML!=')')||a==' ') del(); } formula+=this.innerHTML; // have chosen "^" or "root" if(isNaN(this.innerHTML)&&symbol!=0&&pri==0&&this.innerHTML!='.' ){ if(this.innerHTML=='(') pri=1 ; else { formula2+=')'; symbol=0; } } formula2+=this.innerHTML; formula.trim(); document.getElementById("table1").rows[0].cells[0].innerHTML=formula; } } //= function equal(){ if(formula2.length!=0){ if(symbol!=0){ formula2+=')'; symbol=0; } formula2.trim(); try { document.getElementById("table1").rows[0].cells[0].innerHTML=eval(formula2); formula=eval(formula2).toString(); formula2=formula; flag=1; } catch (Exception) { document.getElementById("table1").rows[0].cells[0].innerHTML="ERROR"; formula=''; formula2=''; flag=1; } } } //c function clear(){ formula=''; formula2=''; document.getElementById("table1").rows[0].cells[0].innerHTML="0"; Clear=1; } //del function del(){ if(flag!=1&&Clear!=1){ if(formula[formula.length-1]=='^'||formula[formula.length-1]==' '){ var k=formula2.lastIndexOf('('); var j=formula2.lastIndexOf(','); formula2 = formula2.substring(0,k-8)+formula2.substring(k+1,j); if(formula[formula.length-1]==' ') formula=formula.substring(0,formula.length-6); else formula=formula.substring(0,formula.length-1); symbol=0; } else{ formula=formula.substring(0,formula.length-1); formula2=formula2.substring(0,formula2.length-1); } document.getElementById("table1").rows[0].cells[0].innerHTML=formula; } } //^ function exponent(){ symbol=1; i=formula2.length-2; cal(); } //root function root(){ symbol=2; i=formula2.length-7; cal(); } // calculate "^" and "root" function cal(){ var temp1='',temp2=''; var str="Math.pow("; for(;i>=0;i--){ var ch=formula2[i]; if(isNaN(ch)&&ch!='.'){ if(ch=='(') { str="(Math.pow(" continue; } else break; } else temp1+=ch; } temp1=temp1.split("").reverse().join(""); // ^ if(symbol==1) formula2=formula2.substring(0,i+1)+str+temp1+","; // root if(symbol==2) formula2=formula2.substring(0,i+1)+str+temp1+",1/"; i=0; } //( function left(){ pri=1; } //) function right(){ var j=formula2.length; var k=formula2.lastIndexOf('('); var temp1,temp2; temp2=eval(formula2.substring(k,j)); formula2= formula2.substring(0,k)+temp2; pri=0; }
该实验比较复杂的地方在于它的容错性,在参考了微软自带计算器后,做了如下设置:
1)初始化界面:
① 显示0;
② 按下等号、删除键: 无反应;
③ 按下运算符号: 显示“0”+“运算符号”;
④ 按下“.”: 显“0”+“.”;
⑤ 按下数字或括号: 显示数字或括号;
2)按下等号:
① 显示结果;
② 按下等号、删除键: 无反应;
③ 按下运算符号: 显示结果+“运算符号”;
④ 按下“.”: 初始化,并显“0”+“.”;
⑤ 按下数字或括号: 初始化,并显示数字或括号;
3)按下c:
返回初始化界面;
4)表达式存在除数为0:
按下等号之后,显示 Infinity;
5)表达式错误:
按下等号之后,显示 ERROR;
6)一次只能选择一个运算符号,括号不算。