[教程]JS从糊涂到明白:一步一步编写计算器2 – 简化代码
2010-07-16 02:11
901 查看
[文章原始发表:This Is WWW : http://www.plrsoft.cn/blog/?p=69 转载请注明出处] |
我要告诉你,完全没问题!
大家先观察这个代码:
<!--content start--> <div id="calc"> <!--这里是显示屏 start--> <div id="screen"><input id="result" readonly="readonly" type="text" value="0" /></div> <!--这里是显示屏 end--> <!--这里是功能键 start--> <div id="button"> <input id="num_1" onclick="javascript:add_num(this.value)" type="button" value="1" accesskey="A" /> <input id="num_2" onclick="javascript:add_num(this.value)" type="button" value="2" /> <input id="num_3" onclick="javascript:add_num(this.value)" type="button" value="3" /> <input id="num_4" onclick="javascript:add_num(this.value)" type="button" value="4" /> <input id="num_5" onclick="javascript:add_num(this.value)" type="button" value="5" /> <input id="num_6" onclick="javascript:add_num(this.value)" type="button" value="6" /> <input id="num_7" onclick="javascript:add_num(this.value)" type="button" value="7" /> <input id="num_8" onclick="javascript:add_num(this.value)" type="button" value="8" /> <input id="num_9" onclick="javascript:add_num(this.value)" type="button" value="9" /> <input id="num_0" onclick="javascript:add_num(this.value)" type="button" value="0" /> <input id="btn_plus" onclick="javascript:add_btn(this.value)" type="button" value="+" /> <input id="btn_cut" onclick="javascript:add_btn(this.value)" type="button" value="-" /> <input id="btn_multi" onclick="javascript:add_btn(this.value)" type="button" value="×" /> <input id="btn_divid" onclick="javascript:add_btn(this.value)" type="button" value="÷" /> <input id="btn_divid" onclick="javascript:add_btn(this.value)" type="button" value="." /> <input id="btn_ce" onclick="javascript:add_btn(this.value)" type="button" value="CE" /> <input id="=" onclick="javascript:get_result()" type="button" value="=" /></div> <!--这里是功能键 end--> </div>
发现没有?其实,这里面很多代码都是重复的! 仔细观察这俩行!
... <input id="num_0" onclick="javascript:add_num(this.value)" type="button" value="0" /> <input id="btn_plus" onclick="javascript:add_btn(this.value)" type="button" value="+" /> ...
请告诉我他们的区别! 是的,他们的区别仅在于value属性、id属性以及ONCLICK的动作不同!那就好办了!干重复的活儿是计算机的强项,而人比计算机更强的功能就是,能灵活的让一件重复的事情出现微妙的变化!
于是,我决定将所有的按键控件都用javascript生成,然后填充到id=button这个DIV中! 所以我们要准备一个初始化函数btn_init(),然后将这个函数放入的ONLOAD事件中代码如下;
<div id="main_div"> <!--content start--> <div id="calc"> <!--这里是显示屏 start--> <div id="screen"><input id="result" readonly="readonly" type="text" value="0" /></div> <!--这里是显示屏 end--> <!--这里是功能键 start--> <div id="button"></div> <!--这里是功能键 end--> </div> <!--content end--> </div>
/*---动态构建按钮控件 start---*/ function btn_init() { btn_list=new Array(1,2,3,4,5,6,7,8,9,0,"+","-","×","÷",".","CE","="); //设置一个数组,存储按键 var button_area = document.getElementById("button"); //这里就是要写入控件的地方 for(var i=0;i<btn_list.length;i++) { //控件的生成,分为两种,一种是数字,一种是非数字,分别绑定不同的动作 if(isNaN(btn_list[i])) //如果不是数字,则绑定add_btn()事件 否则绑定add_num() { //进行一个特殊功能的处理:= if(btn_list[i]=="="){ button_area.innerHTML+="<input type='button' value='=' id='=' onclick='javascript:get_result()'/>"; }else{ button_area.innerHTML+=" <input type=\"button\" value=\""+btn_list[i]+"\" id=\"btn_"+btn_list[i]+"\" onclick=\"javascript:add_btn(this.value)\"/>"; } }else{ button_area.innerHTML+=" <input type=\"button\" value=\""+btn_list[i]+"\" id=\"btn_"+btn_list[i]+"\" onclick=\"javascript:add_num(this.value)\"/>"; } } } /*---动态构建按钮控件 end---*/
OK,现在我们的代码生成了!
点这里运行一下! 看,他跑起来了!
是的,它跑起来了!但是,还远远达不到我们的目标!20行代码!怎么实现?继续观察,我们发现,很多行代码主要花在了判断上,那么我们能不能将一些功能合并呢?比方说,不管按键是数字还是非数字,一律使用“add_btn()”,抛弃掉add_num()和get_result()函数,这样,我们在生成控件环节可以节省很多的代码。同时,将add_btn()、add_num()、get_result()三个函数合并,也能缩减代码数量,也能抛弃掉判断特殊功能的代码(比如要多一个判断语句判断“=”以便分配特殊动作)!
说干就干,我们先缩短代码生成函数
/*---动态构建按钮控件 start---*/ function btn_init() { btn_list=new Array(1,2,3,4,5,6,7,8,9,0,"+","-","×","÷",".","CE","="); //设置一个数组,存储按键 var button_area = document.getElementById("button"); //这里就是要写入控件的地方 for(var i=0;i<btn_list.length;i++) { button_area.innerHTML+=" <input type=\"button\" value=\""+btn_list[i]+"\" id=\"btn_"+btn_list[i]+"\" onclick=\"javascript:add_btn(this.value)\"/>"; } } /*---动态构建按钮控件 end---*/
JUST 11行! 除掉注释,然后将for循环合并成一行,只剩下5行 ,这下清爽了吧!这里5行,加上先前构建最最最简单的计算器的功能实现代码14行,一共是19行!说20行还多呢!
再让我们来合并add_btn()、add_num()、get_result()三个函数,同时,我们也进一步的修正前面还存在的一些小BUG,比如,归零后,输入的第一个数字前老会带一个0的囧况!代码如下:
is_res=false; //设定全局变量 is_res function add_btn(act){ //向显示屏添加运算符号 if(is_res==true) { result.value="0"; //显示屏归零 is_res=false; //将IS_RES变量标记为键盘输入状态,表示当前显示屏的数字是输入的,而非运算结果 } if (act=="CE"){result.value="0";} else if (act=="="){ /*这里增加对=的特殊处理 亦即合并get_result()函数--*/ var res_temp=result.value; //设置一个临时变量来进行运算符替换,以免将中间过程显示到屏幕上 res_temp=res_temp.replace(/[×]/g,"*"); //将所有的乘号换成* res_temp=res_temp.replace(/[÷]/g,"/"); //将所有的除号换成/ result.value=eval(res_temp); is_res=true; //将IS_RES变量标记为结果状态,标示当前显示屏的数字是运算结果,而非输入状态。 /*---合并结束--*/ } else if(isNaN(act)==false) { if(result.value==0){result.value="";} result.value+=act } //合并 add_num(),将数字原本的显示在屏幕上 else { /*----设置一个临时变量来进行正则替换,以免将中间过程显示到屏幕上--*/ var result_temp =result.value+act; var temp_parr = ""; /*---------------寻找整个运算式第一个数字为0且其后所跟的符号不是运算符和小数点的数字---------------*/ var parr1=/(^0+)([0-9])/; if(parr1.test(result_temp)) { //设定替换语句,将整个运算式第一个数字为0开头的数字去除 temp_parr = result_temp.match(parr1)[2]; result_temp=result_temp.replace(parr1,temp_parr); } /*---------------寻找整个运算式第一个数字为负号 - 的数字---------------*/ var parr2=/(^-*)(0*)(.*)/; if(parr2.test(result_temp)) { //将非负号的符号去除 temp_parr = result_temp.match(parr2)[1]+result_temp.match(parr2)[3]; result_temp=result_temp.replace(parr1,temp_parr); } /*---------------将当前运算式中除运算符号外的所有数字取出---------------*/ var parr3=/(?=[+-×÷]){1}([0-9.]+)(?=[+-×÷]){1}/g; if(parr3.test(result_temp)) { temp_parr = result_temp.match(parr3); //用match方法取出当前式子中的数字 for(var i=0;i<temp_parr.length;i++) { var nozero_parr=Number(temp_parr[i]); //让每一个数字都成为一个合法数值 result_temp=result_temp.replace(temp_parr[i],nozero_parr); } } /*---------------寻找算式中连续出现的运算符号,诸如++,x-+等---------------*/ var parr4=/[^0-9]{2,}/g; if(parr4.test(result_temp)) { temp_parr = result_temp.match(parr4); for(var i=0;i<temp_parr.length;i++) { var cur_sign = new Array(temp_parr[i].substring(0,1),temp_parr[i].substring(1,2)); //取出符号串的前两个符号 //创建一个数组,将取出来的符号串的第一个符号和第二个符号存入一个数组 var temp_sign=""; if(cur_sign[1]=="-") { temp_sign=cur_sign[0]+cur_sign[1]; }else{ temp_sign=cur_sign[0]; } //如果第二个符号不是负号,那么只保留第一个符号,否则就保留两个符号 result_temp=result_temp.replace(temp_parr[i],temp_sign); } } result.value=result_temp; } }
OK,这样,我们就将代码简化完成了!
查看运行效果
很完美!我们在简化的同时,还做了一些工作,那就是为程序的以后扩展做出了铺垫。
一个程序的可扩展性和可方便扩展性是很重要的,比方说,以后如果你要给这个计算器加入开方、乘方、计算正弦余弦的功能,总不能超级麻烦的先在页面添加 input 控件,然后指定一个动作,再去修改JAVASCRIPT吧,那样的代码,只会越来越庞杂。所以,再最开始构建程序的时候,就要考虑到以后如何可以很方便的直接修改JS代码就可以,要基本上做到代码跟页面架构相分离,这种分离有利于页面表现和页面内容的维护。
下一节,将会讲到如何进行功能扩展。
相关文章推荐
- [教程]JS从糊涂到明白:一步一步编写计算器1——构建和兼容
- [教程]JS从糊涂到明白:一步一步编写计算器3 – 功能扩展
- 用js编写的简单的计算器代码程序
- 用js编写的简单的计算器代码程序
- 仅用50行代码实现一个Python编写的计算器的教程
- 《『若水新闻』客户端开发教程》——09.代码编写(1)
- Java Socket通讯客户端代码编写教程
- 编写跨浏览器的javascript代码必备[js多浏览器兼容写法]
- Xamarin iOS教程之编辑界面编写代码
- js编写当天简单日历效果【实现代码】
- 编写跨浏览器的javascript代码必备[js多浏览器兼容写法]
- C#基础视频教程4.2 如何编写简单的计算器
- js学习入门教程笔记:css+html+js用户注册代码实现
- 编写高质量代码改善C#程序的157个建议——建议82:Parallel简化但不等同于Task默认行为
- js高级代码编写
- JS编程艺术笔记(2)-编写JS代码的几点建议
- vs2005视频教程 之 编写可复用的代码-概述 [视频]
- 编写针对IE的JS代码两种编写方法
- 用python40行代码编写的计算器
- Android开发视频教程之三十一(代码编写 三)