JavaScript实现一个简易的计算器实例代码


Posted in Javascript onMay 10, 2018

自己期末复习的时候就一直想要写一个计算器,闲暇的时候也在想具体怎么实现,觉得应该不难,但就是想写。昨天终于可以开始动工,刚开始还以为实现出来需要一个周左右至少两天的时间,想着实现完我就可以先回家两天了。但没想到整个实现过程算比较顺利吧,昨天用了大概六个小时完成了从设计到具体实现。

有大概一个月没怎么写代码了,整个大脑都不适应,反应也慢,一些基本的东西都有点模糊不清了。可能是原来就没有太理解,再加上没有其余练习,导致效率有些低。

正文

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();

正常显示界面

JavaScript实现一个简易的计算器实例代码

错误提示界面

JavaScript实现一个简易的计算器实例代码

效果实现: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]。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js function使用心得
May 10 Javascript
javascript中检测变量的类型的代码
Dec 28 Javascript
jQuery的attr与prop使用介绍
Oct 10 Javascript
jquery获取当前日期的方法
Jan 14 Javascript
javascript显示上周、上个月日期的处理方法
Feb 03 Javascript
javascript中对Date类型的常用操作小结
May 19 Javascript
学习Angularjs分页指令
Jul 01 Javascript
javascript 实现动态侧边栏实例详解
Nov 11 Javascript
Bootstrap Img 图片样式(推荐)
Dec 13 Javascript
js中获取键盘按下键值event.keyCode、event.charCode和event.which的兼容性详解
Mar 15 Javascript
jQuery实现动态删除LI的方法
May 30 jQuery
vuex实现购物车功能
Jun 28 Javascript
浅谈node.js 命令行工具(cli)
May 10 #Javascript
Js经典案例的实例代码
May 10 #Javascript
Vue使用vux-ui自定义表单验证遇到的问题及解决方法
May 10 #Javascript
vuex与组件联合使用的方法
May 10 #Javascript
vue项目中公用footer组件底部位置的适配问题
May 10 #Javascript
解决vue 按钮多次点击重复提交数据问题
May 10 #Javascript
vue-router3.0版本中 router.push 不能刷新页面的问题
May 10 #Javascript
You might like
PHP 清空varnish 缓存的详解(包括指定站点下的)
2013/06/20 PHP
php微信公众平台开发(一) 配置接口
2016/12/06 PHP
php+ajax实现仿百度查询下拉内容功能示例
2017/10/20 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
2018/06/16 PHP
自定义Laravel (monolog)日志位置,并增加请求ID的实现
2019/10/17 PHP
Yii框架学习笔记之应用组件操作示例
2019/11/13 PHP
Google的跟踪代码 动态加载js代码方法应用
2012/11/12 Javascript
jquery对ajax的支持介绍
2013/12/10 Javascript
Javascript实现简单的富文本编辑器附演示
2014/06/16 Javascript
js中各种类型的变量在if条件中是true还是false
2014/07/16 Javascript
jQuery插件实现图片轮播特效
2016/06/16 Javascript
Node.js实现兼容IE789的文件上传进度条
2016/09/02 Javascript
JS区分Object与Aarry的六种方法总结
2017/02/27 Javascript
node.js平台下的mysql数据库配置及连接
2017/03/31 Javascript
一篇看懂vuejs的状态管理神器 vuex状态管理模式
2017/04/20 Javascript
vue脚手架及vue-router基本使用
2018/04/09 Javascript
Vue CLI3 开启gzip压缩文件的方式
2018/09/30 Javascript
微信公众号平台接口开发 获取access_token过程解析
2019/08/14 Javascript
js实现AI五子棋人机大战
2020/05/28 Javascript
[43:58]DOTA2上海特级锦标赛C组败者赛 Newbee VS Archon第二局
2016/02/27 DOTA
wxPython窗口的继承机制实例分析
2014/09/28 Python
Python中endswith()函数的基本使用
2015/04/07 Python
python控制台中实现进度条功能
2015/11/10 Python
不同版本中Python matplotlib.pyplot.draw()界面绘制异常问题的解决
2017/09/24 Python
python: 判断tuple、list、dict是否为空的方法
2018/10/22 Python
python机器学习库xgboost的使用
2020/01/20 Python
flask框架渲染Jinja模板与传入模板变量操作详解
2020/01/25 Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
2020/03/08 Python
美国网上购买眼镜:Eyeconic
2017/07/29 全球购物
Jack Rogers官网:美国经典的女性鞋靴品牌
2019/09/04 全球购物
《唯一的听众》教学反思
2014/02/20 职场文书
新闻传媒系求职信范文
2014/04/19 职场文书
小学英语教师先进事迹
2014/05/28 职场文书
微笑面对生活演讲稿
2014/09/23 职场文书
年底个人总结范文
2015/03/10 职场文书
师范生小学见习总结
2015/06/23 职场文书