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 相关文章推荐
jquery text()要注意啦
Oct 30 Javascript
js+JQuery返回顶部功能如何实现
Dec 03 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
Jul 15 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
Apr 17 Javascript
Jquery基础之事件操作详解
Jun 14 Javascript
jQuery实现复制到粘贴板功能
Feb 11 Javascript
微信小程序 Buffer缓冲区的详解
Jul 06 Javascript
Vue.js中extend选项和delimiters选项的比较
Jul 17 Javascript
JavaScript 截取字符串代码实例
Sep 05 Javascript
如何基于原生javaScript生成带图片的二维码
Nov 21 Javascript
微信小程序抽奖组件的使用步骤
Jan 11 Javascript
vue-video-player 断点续播的实现
Feb 01 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
几个学习PHP的网址
2006/11/25 PHP
php简单实现MVC
2015/02/05 PHP
详解PHP序列化反序列化的方法
2015/10/27 PHP
PHP实现GIF图片验证码
2015/11/04 PHP
PHP中有关长整数的一些操作教程
2019/09/11 PHP
JavaScript高级程序设计 XML、Ajax 学习笔记
2011/09/10 Javascript
JS Jquery 遍历,筛选页面元素 自动完成(实现代码)
2013/07/08 Javascript
cookie.js 加载顺序问题怎么才有效
2013/07/31 Javascript
jquery 显示*天*时*分*秒实现时间计时器
2014/05/07 Javascript
jQuery插件Timelinr 实现时间轴特效
2015/10/04 Javascript
理解JavaScript中Promise的使用
2016/01/18 Javascript
jQuery ajax时间差导致的变量赋值问题分析
2016/01/22 Javascript
jQuery插件支持同一页面被多次调用
2016/02/14 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
ES6关于Promise的用法详解
2018/05/07 Javascript
Bootstrap Table列宽拖动的方法
2018/08/15 Javascript
jquery实现点击弹出对话框
2020/02/08 jQuery
手机浏览器唤起微信分享(JS)
2020/10/11 Javascript
Vue——解决报错 Computed property &quot;****&quot; was assigned to but it has no setter.
2020/12/19 Vue.js
[01:06:42]VP vs NewBee Supermajor 胜者组 BO3 第二场 6.5
2018/06/06 DOTA
python简单程序读取串口信息的方法
2015/03/13 Python
分享一个常用的Python模拟登陆类
2015/03/29 Python
python采集百度百科的方法
2015/06/05 Python
TensorFlow平台下Python实现神经网络
2018/03/10 Python
Python使用Shelve保存对象方法总结
2019/01/28 Python
pycharm配置pyqt5-tools开发环境的方法步骤
2019/02/11 Python
关于Python 的简单栅格图像边界提取方法
2019/07/05 Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
2019/08/12 Python
Python虚拟环境的创建和包下载过程分析
2020/06/19 Python
python打开文件的方式有哪些
2020/06/29 Python
详解KMP算法以及python如何实现
2020/09/18 Python
Bugatchi官方网站:男士服装在线
2019/04/10 全球购物
Auguste The Label官网:澳大利亚一家精品女装时尚品牌
2020/06/14 全球购物
自荐信模版
2013/10/24 职场文书
大学毕业生自荐书怎么写?
2014/01/06 职场文书
Go 语言结构实例分析
2021/07/04 Golang