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 操作css实现代码
Jun 11 Javascript
深入解析JavaScript中的数字对象与字符串对象
Oct 21 Javascript
node.js实现快速截图
Aug 27 Javascript
Vue数据驱动模拟实现1
Jan 11 Javascript
JavaScript原生节点操作小结
Jan 17 Javascript
Angular.js自动化测试之protractor详解
Jul 07 Javascript
5 种JavaScript编码规范
Jan 30 Javascript
Vue 动态组件components和v-once指令的实现
Aug 30 Javascript
jQuery擦除插件eraser使用方法详解
Jan 11 jQuery
解决vue+ element ui 表单验证有值但验证失败问题
Jan 16 Javascript
vue 自定指令生成uuid滚动监听达到tab表格吸顶效果的代码
Sep 16 Javascript
vue form表单post请求结合Servlet实现文件上传功能
Jan 22 Vue.js
浅谈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
Apache+php+mysql在windows下的安装与配置图解(最新版)
2008/11/30 PHP
解析php DOMElement 操作xml 文档的实现代码
2013/05/10 PHP
解析关于wamp启动是80端口被占用的问题
2013/06/21 PHP
解析VS2010利用VS.PHP插件调试PHP的方法
2013/07/19 PHP
dedecms中使用php语句指南
2014/11/13 PHP
thinkphp验证码的实现(form、ajax实现验证)
2016/07/28 PHP
详解EventDispatcher事件分发组件
2016/12/25 PHP
Extjs4 关于Store的一些操作(加载/回调/添加)
2013/04/18 Javascript
JS下拉框内容左右移动效果的具体实现
2013/07/10 Javascript
JQuery操作iframe父页面与子页面的元素与方法(实例讲解)
2013/11/20 Javascript
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
简介JavaScript中的setHours()方法的使用
2015/06/11 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
2020/03/30 Javascript
JS实现在状态栏显示打字效果完整实例
2015/11/02 Javascript
javascript动态生成树形菜单的方法
2015/11/14 Javascript
实例详解jQuery的无new构建
2016/08/02 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
2016/08/12 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
2017/01/13 Javascript
JavaScript对象_动力节点Java学院整理
2017/06/23 Javascript
JavaScript判断输入是否为数字类型的方法总结
2017/09/28 Javascript
Vue兼容ie9的问题全面解决方案
2018/06/19 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
2019/03/06 Javascript
小程序显示弹窗时禁止下层的内容滚动实现方法
2019/03/20 Javascript
js实现批量删除功能
2020/08/27 Javascript
Python3实现的简单验证码识别功能示例
2018/05/02 Python
python实现弹窗祝福效果
2019/04/07 Python
pyqt5 实现工具栏文字图片同时显示
2019/06/13 Python
python实现将视频按帧读取到自定义目录
2019/12/10 Python
新奇的小玩意:IWOOT
2016/07/21 全球购物
衰败城市英国官网:Urban Decay英国
2020/04/29 全球购物
《长城和运河》教学反思
2014/04/14 职场文书
2015年端午节国旗下演讲稿
2015/03/19 职场文书
会议通知范文
2015/04/15 职场文书
SpringBoot整合RabbitMQ的5种模式实战
2021/08/02 Java/Android
Anaconda配置各版本Pytorch的实现
2021/08/07 Python
无线电知识基础入门篇
2022/02/18 无线电