JavaScript实现一个简易的计算器实例代码
自己期末复习的时候就一直想要写一个计算器,闲暇的时候也在想具体怎么实现,觉得应该不难,但就是想写。昨天终于可以开始动工,刚开始还以为实现出来需要一个周左右至少两天的时间,想着实现完我就可以先回家两天了。但没想到整个实现过程算比较顺利吧,昨天用了大概六个小时完成了从设计到具体实现。
有大概一个月没怎么写代码了,整个大脑都不适应,反应也慢,一些基本的东西都有点模糊不清了。可能是原来就没有太理解,再加上没有其余练习,导致效率有些低。
正文
html代码:
<div class="errorhint" id="errorhint"><img src="https://github.com/crystalyy/calculator/blob/master/img/error.png?raw=true"></div> <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函数第一次使用,w3c上对它的定义如下
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]。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: php合并图片,生成gif动态图片,保存到指定目录
下一篇: 如何利Mcrypt扩展库进行加密和解密
推荐阅读
-
JavaScript实现一个简易的计算器实例代码
-
一个鼠标移动滑出层效果的实现代码_javascript技巧
-
一个鼠标移动滑出层效果的实现代码_javascript技巧
-
Javascript实现滚动图片新闻的实例代码_javascript技巧
-
javascript判断一个字符串或者数组里面出现最多的元素及其出现的次数(代码实例)
-
实现JavaScript MVC样式框架的简单代码实例
-
Javascript 数组添加一个 indexOf 方法的实现代码_javascript技巧
-
详细介绍一个利用html+css实现叮当猫的实例代码
-
详解css3+javascript实现翻页的实例代码
-
jQuery实现可收缩展开的级联菜单实例代码_javascript技巧