這次帶給大家JS實作一個簡易的計算器步驟詳解,JS實作一個簡易的計算器的注意事項有哪些,下面就是實戰案例,一起來看一下。
自己期末複習的時候就一直想要寫一個計算器,閒暇的時候也在想具體怎麼實現,覺得應該不難,但就是想寫。昨天終於可以開始動工,剛開始還以為實現出來需要一個週左右至少兩天的時間,想著實現完我就可以先回家兩天了。但沒想到整個實現過程算比較順利吧,昨天花了大概六個小時完成從設計到具體實現。
大概一個月沒怎麼寫程式碼了,整個大腦都不適應,反應也慢,一些基本的東西都有點模糊不清了。可能是原來就沒有太理解,再加上沒有其餘練習,導致效率有些低。
正文
html程式碼:
#<p class="errorHint" id="errorHint"><img src="https://github.com/crystalYY/calculator/blob/master/img/error.png?raw=true"></p> <table cellpadding="0"> <tr> <th colspan="5">计算器</th> </tr> <tr> <td colspan="5"> <input type="text" value="0" name="showResult"> </td> </tr> <tr> <td><button>7</button></td> <td><button>8</button></td> <td><button>9</button></td> <td><button class="setChange" id="backSpace">退格</button></td> <td><button class="setChange" id="clearNum">C</button></td> </tr> <tr> <td><button>4</button></td> <td><button>5</button></td> <td><button>6</button></td> <td><button>+</button></td> <td><button>-</button></td> </tr> <tr> <td><button>1</button></td> <td><button>2</button></td> <td><button>3</button></td> <td><button>*</button></td> <td><button>/</button></td> </tr> <tr> <td><button>0</button></td> <td><button>.</button></td> <td><button>%</button></td> <td colspan="2"><button class="setChange" id="gainResult">Enter</button></td> </tr> </table> <script type="text/javascript" src='index.js'> </script>
CSS程式碼:
*{margin: 0px; padding: 0px;} .errorHint{position: absolute; left: 130px; top:-282px;} .showError{border:1px solid red;} table{ border: 2px solid #996c33; width: 550px; padding: 10px; margin: 150px auto; background:url(https://github.com/crystalYY/calculator/blob/master/img/bg2.jpg?raw=trueg) left center no-repeat; border-radius: 10px;} table td{ text-align: center; width: 100px; height: 40px; padding-left: 2px; padding-bottom: 2px; } table th{ font-size: 18px; font-family:'楷体'; color: #8B0000; } table td button{ width: 98%; height: 98%; font-size: 16px; font-family: 'Microsoft yahei'; background: none; color: #8B4726; outline:none; border:1px solid #000; border-radius: 5px; cursor: pointer; } table td input{ width: 100%; margin: 10px 0; padding: 5px; border:1px solid #996c33; box-sizing: border-box; text-align: right; font-size: 16px; font-family: 'Microsoft yahei'; }
JS程式碼:
var oinput=document.getElementsByTagName('input')[0]; //获取外部样式 function getStyle(obj, name) { if(obj.currentStyle) { return obj.currentStyle[name]; } else { return getComputedStyle(obj, false)[name]; } } //渐变动画 function move(obj,attr,tar){ clearInterval(obj.timer); obj.timer=setInterval(function(){ var cur=parseInt(getStyle(obj,attr)); var itarget=parseInt(tar); var speed=(itarget-cur)/6; speed=speed>0?Math.ceil(speed):Math.floor(speed); obj.style[attr]=parseInt(getStyle(obj,attr))+speed+'px'; if(speed==0){ clearInterval(obj.timer); } },30); } //事件绑定函数 function addEvent(obj,ev,fun){ if(obj.attachEvent){ obj.attachEvent('on'+ev,fun); }else{ obj.addEventListener(ev,fun,false); } } //阻止默认行为 function stopEvent(ev){ var e=ev||window.event; if(e.preventDefault){ e.preventDefault(); } else{ e.returnValue=false;//ie } } //计算最终结果 function getResult(){ function evalResult(){ var result=eval(oinput.value); return result; } //捕获异常 try{ var x=evalResult(); return x; } catch (e){ oinput.className='showError'; var errorHint=document.getElementById('errorHint'); move(errorHint,'top',0); setTimeout(function(){ oinput.className=''; move(errorHint,'top',-282); },2000); return oinput.value; } } //文本框获取焦点,错误提示消失 //按下回车得到结果 function enterResult(ev){ var e=ev||window.event; if(e.keyCode==13){ stopEvent(ev);//阻止enter键的默认行为 var result=getResult(); oinput.value=result; } } //绑定点击事件 function init(){ var otable=document.getElementsByTagName('table')[0]; addEvent(otable,'keydown',function(ev){ enterResult(ev); }); addEvent(otable,'click',function(ev){ stopEvent(ev); var e=ev||window.event; var itat=e.target||e.srcElement; var obtns=document.getElementsByTagName('button'); if(itat.nodeName.toLowerCase()=='button'){ for(var i=0;i<obtns.length;i++){ obtns[i].style.borderColor='#000'; } itat.style.borderColor='white'; if(itat.className!='setChange'){ if(oinput.value=='0'){ oinput.value=''; oinput.value+=itat.innerHTML; } else{ oinput.value+=itat.innerHTML; } }else{ if(itat.id=='backSpace'){ oinput.value=oinput.value.toString().slice(0,-1); } else if(itat.id=='clearNum'){ oinput.value='0'; }else{ var result=getResult(); oinput.value=result; } } } }); } init();
正常顯示介面
##錯誤提示介面效果實作:http://codepen.io/crystalYY/pen/jAkNVz
實作想法
1.使用table畫出整個介面。
借鑒了其他人已經實現了的結構,發現他們有一些人沒有直接在td裡寫1,2,3或退格甚麼的,而是又嵌套了一個button,我其實到現在也沒有太理解為什麼要這樣,只是在排版的時候感覺到有些作用:因為margin對td 不起作用,只能設定padding。2.使用eval函數計算最終結果,並捕獲異常
function getResult(){ function evalResult(){ var result=eval(oinput.value); return result; } //捕获异常 try{ var x=evalResult(); return x; } catch (e){ oinput.className='showError'; var errorHint=document.getElementById('errorHint'); move(errorHint,'top',0); setTimeout(function(){ oinput.className=''; move(errorHint,'top',-282); },2000); return oinput.value; } }
eval() 函數可計算某個字串,並執行其中的JavaScript 程式碼。有了這個函數得到最終結果就很容易了。我的想法是在使用者輸入要計算的式子時不加幹預,最終的計算從input輸入框中獲取value值,然後把這個value值作為參數傳遞給eval,並使用try catch(exception)來捕獲並處理異常。
3.透過事件代理程式綁定事件
因為每個button都需要有一個點擊事件,如果一個一個去綁定,會導致程式碼十分的不簡潔,而且效率也非常低。這時就可以考慮使用事件代理,由於事件冒泡的原理,我們可以把點擊事件綁定在table上,然後透過判斷事件發生的具體物件來做出不同的反應,調用不同的函數。4.其他效果
可以依照自己的設計思路,加入其他的效果。我主要是添加了一個錯誤提示的動畫:如果eval函數拋出異常,則從上面緩慢滑下一個圖片,並且透過setTimeout來設定了停留的時間。
5.注意細節
在設定enter鍵按下獲得結果的時候,keydown事件物件應該是整個table,並且應該阻止enter鍵的預設行為取得元素樣式時需要寫一個相容函數,因為obj.style.attr只能取得行間樣式,要像取得外部樣式需要用getComputedStyle(obj,false)[attr]或相容IE的obj.currentStyle[attr ]。
以上是JS實作一個簡易的計算器步驟詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!