JS实现HTML在线计算器文章摘要
在前面的章节中,我们已经清楚地知道如何通过Table或DIV对一个HTML在线计算器进行布局。所以本项目演练的核心目的,主要是利用JavaScript编程的方式,来实现该在线计算器的功能,实现效果如图11-2所示。
图11-2 在线计算器运行效果
我们先来分析一下该项目要实现的功能主要包含哪些方面:
(1) 当输入0~9的数字和5个标准运算符(%,÷,*,-,+)及小数点时,如实反应在结果框中,便于用户核对输入。
(2) “AC”按钮表示清除所有的结果框内容,“<-”回退则只删除最后一个字符。
(3) “=”按钮对结果框中的用户输入的运算表达式进行计算,并展示其运算结果。
(4) “+/-”按钮表示对某个数字进行正负数切换。
(5) 如果用户输入的表达式出现错误,无法计算其结果,则在结果框提示错误信息。
(6) 不能重复地输入运算符,比如5+-++*6,这样的表达式是不允许存在的。
首先,本计算器相对于之前的计算器布局做了两处调整:一是添加了回退按钮,即可以用来删除结果框中的一个字符;二是结果框从DIV换成了文本框,因为文本框本身就是用来做输入用的,更加符合通常的要求,也符合用户的使用习惯。同时,这样的设计还可以让用户直接在文本框中输入,提高输入效率,而不是单纯地通过点击按钮来进行。但是同时,这样的输入也必须要注意到,用户输入的正确性,需要对输入部分进行检测。
同样的方式,我们来对上述的7个功能点进行细致的分析,找到对应的解决方案:
1.运算表达式的输入
运算表达式的输入其实核心点就在于将对应按钮的值,如1,3,+等添加在结果框的最后。那么我们可以使用代码如:“document.getElementById(“result”).value += “3””这样的代码来完成按钮的输入。当然,我们也可以选择让用户自行输入到文本框中。
2.清除结果功能
整体清除结果框的内容,只需要将该结果框的内容设置为一个空字符串即可,比如代码可能是“document.getElementById(“result”).value = “””这样的。
对于回退按钮来说,由于删除的是最后一个字符,所以我们可以使用JavaScript的字符串处理函数substring来对字符串进行截取,截取位置是从0到字符串的长度减1的位置,这样就可以将最后一个位置的字符排除掉。
3.计算结果功能
我们既然已经将运算表达式输入进去了,甚至有可能是连续的运算,这个时候,如何能够对结果框中的一段普通的文本进行数学运算,变成一个非常棘手的问题。好在,JavaScript为我们提供了一个非常高效而方便的函数:“eval()”。
eval函数是一个特别的函数,可以将一段字符串解析为一段标准的JS代码来执行。我们可以来看看如下的代码实例:
<script> |
根据上述代码实例,我们可以看到,字符串"1+2-3+4-5*6/7+8"和"alert('hello')"经过eval函数的解析处理后,会变成一个标准的JS表达式并且执行相应的结果运算。这便是这个函数的神奇之处。所以只要我们输入的表达式是正确的,便可以直接被当作一个代码来执行。
4.正负号切换功能
对一个数字进行正负号切换,其核心就是在数字前面添加或去除“-”号,基于此,问题的解决方案有两种:一是直接用0来对其数字进行减法运算,二是获取到该数字的第1位的ASCII码,如果是“-”号则将其删除,变为正数,否则,直接在该数字的最前面添加一个负号即可。两种方式都不复杂,大家任选一种方案即可。
5.错误提示信息
对于一个数学表达式来说,出现错误的情况将是非常多的,所以我们很难通过if…else…的方式将所有可能出错的情况全部考虑进去。那么在这种情况下呢,我们建议大家使用JavaScript的异常处理机制。通过捕获eval()函数在运算表达式是出现的异常来提示用户出错信息,这样将会更加容易处理,而且不用将精力关注在错误类型的实现上。
6.重复运算符验证
虽然所有的异常和错误我们都可以通过异常处理机制轻松的处理,但是对于用户体验来说却不见得是很好的一种方法。比如用户不小心将运算表达式输错了,这个时候虽然我们会有比较友好的提示,但是却需要让用户再输入一遍。所以最好的方式不是提示错误,而是不要给用户提供犯错误的机会,比如前面章节中给大家提到过的,一个文本框只能限制用户输入数字和小数点,不允许输入其他内容。那么在本计算器当中,我们为什么不可以利用程序去帮助用户减少犯错误的机会呢。
比方说,针对这种重复运算符的情况,我们该如何来避免呢?可以有两种方案:一是检测用户输入的最后一个字符是数字还是符号,如果是符号则不允许再输入一个符号。另外一种方案是每当输入了一个符号后,设置某个标志为true,只有输入了数字后,才将该标志设置为false,表示此时可以输入符号。两种方案,任选一红番区可,复杂度差别不大。
我们仍然按照上述的功能点分析思路,来一步一步实现这些功能。首先当然是页面的布局,这一点在前面的项目实战中已经有所涉及,所以不再重复讲解。唯一需要注意的是我们将结果框从DIV修改成了Input文本框,所以此处的HTML代码是这样的:
<div> |
当然,其对应的CSS属性也做了小幅调整。细节此处不再赘述,需要的读者可查看最后的整体代码部分。接下来我们按照功能点一个一个来看看其实现方式:
1.数字按钮的输入,通过在各按钮处响应单击事件传递不同的参数实现,代码如下:
function clickButton(number) { } |
2.清除和删除功能:
// 删除所有内容 function clearResult() {
// 删除最后一位 |
3.结果计算及错误提示:
// 计算最终结果 |
4.正负号切换:
function switchSymbol() { |
5.重复运算符验证,定义一个全局变量,通过修改该全局变量的值来决定是否可以输入运算符号,代码如下:
var isInputSymbol = false; // 全局变量,false表示可以输入
// 解决符号重复输入的问题 |
此处需要注意一下的是,当我们成功输入了一个数字以后(即在函数clickButton()中),我们必须将该变量的值修改为false,从而告诉脚本此时可以输入符号。clickButton的代码修改如下:
function clickButton(number) { isInputSymbol = false; } |
最后,我们来看看计算器按键的调用,只列举部分代码调用如下:
<body> |
别看一个小小的计算器,其中暗藏不少BUG,非常考验我们对细节的控制。比如上述的代码,初一看其实是没有什么问题了的。但是我们再进行仔细的测试会发现,还是有一些问题需要我们进行更精确的控制。
由于代码限制了用户只能输入18位,所以并没有考虑到实际的情况,而且这18位是表达式的长度,而不是一个数字的长度,所以与我们真实的计算器的运算规律是有所差别的。当然,这样的问题其实解决方案并不难,我们可以设置一个隐藏的元素,如一个DIV或一个文本框,将其隐藏起来,把用户输入的所有内容重新串成一个表达式,当单击“=”号时,直接从该隐藏的文本框中提取表达式从面运算其结果即可。
另外一个方面,我们会发现,虽然我们很好地处理了运算符的连续输入的问题,但是并没有处理小数点的连续输入。而且还有一个更需要注意的问题,即使我们利用类似运算符重复的处理方式很好地处理了连续输入的小数点,让其不能够进行连续输入,但是类似这种形式的数字:“56.34.56.89”其实也是一个不合格的数值,但是小数点并不连续,所以这也是我们需要规避的问题。那么像这种问题,又该如何处理呢?
其实方法也是雷同的,通过设定标志变量来决定是否用户还可以继续输入小数点。比如我们可以设定一个标志变量,假设称为isInputPoint,默认值为false,表示还没有输入小数点,可以允许小数点的存在。这个跟符号的判断一样,但是重点的区别在于,什么时候可以允许再输入小数点呢,不是输入了一个数字以后可以允许再输入,而是只有当输入了一个运算符以后,才允许输入一个小数点。这样就可以实现对小数点的限制,核心代码如下:
// 小数点重复的问题 |
当然,上述代码只是表达其核心思想,要将该代码运行起来,我们还需要定义全局变量,还需要修改clickSymbol()函数等。那么这样我们的计算器功能就实现得很完整了吗?答案是否定的,笔者再给大家举一个例子,比如我们现在可以试着输入一个运算表达式“025-6”,我们可以看看答案是多少?你并没有看错,答案是15,而不是19,很显然这个表达式是有问题的。所以0不能作为一个整数的开头,只能作为一个小数的开头,那么这样的功能点又该如何用代码来进行控制呢?对于这一功能的实现,就留给大家来进行处理了,此处不再详细讲解。
最后,对本项目进行一个简单的总结。一方面我们期望通过该项目的演练让大家充分理解到,开发思路和重要性,其实开发思路本身就是我们的算法。只有把思路想得很明白了,我们再用代码来实现才会更加有自信。另外一方面,我们的代码必须要考虑各种可能的测试场景,设计有针对性的测试用例,而不是用最普通的测试简单试一下,发现没有问题就觉得代码已经可以正常工作了,还是那句话,质量意识才是关键,这跟编程能力无关。作为一个高级程序员,作为一个软件开发或软件测试工程师,都是如此。
版权所有,转载本站文章请注明出处:蜗牛学院在线课堂, http://www.woniuxy.com/note/207
14
Jun
19
Apr
14
Jun
11
May
05
Jun
17
Mar
11
May
21
May
21
May
26
Apr
聚圣源姓王女孩起什么名字瓷都免费测名韩姓起名韩姓男孩子的名字大全鼠年李姓男孩起名字熊起名宝宝名字大全刀客家的女人圆字起名大全广州市中小学教师继续教育网名誉侵权民事起诉状洛薇傅沉渊小说免费阅读木起名字大全男孩子按姓氏起名大全免费男孩起名字姓于捡石头价值近百万罪域演员表生成八字生辰八字免费起名写给公司起名字的软件宝宝起名字 测试易经起名字公司测试打分属鼠 取名起名大全小孩起名宝典新生儿mantahaya17新车上牌下山虎图片铝门窗起名不爱红装爱武装zjgrc维字起名含义我爱的人歌词我的少女时代百度云淀粉肠小王子日销售额涨超10倍罗斯否认插足凯特王妃婚姻让美丽中国“从细节出发”清明节放假3天调休1天男孩疑遭霸凌 家长讨说法被踢出群国产伟哥去年销售近13亿网友建议重庆地铁不准乘客携带菜筐雅江山火三名扑火人员牺牲系谣言代拍被何赛飞拿着魔杖追着打月嫂回应掌掴婴儿是在赶虫子山西高速一大巴发生事故 已致13死高中生被打伤下体休学 邯郸通报李梦为奥运任务婉拒WNBA邀请19岁小伙救下5人后溺亡 多方发声王树国3次鞠躬告别西交大师生单亲妈妈陷入热恋 14岁儿子报警315晚会后胖东来又人满为患了倪萍分享减重40斤方法王楚钦登顶三项第一今日春分两大学生合买彩票中奖一人不认账张家界的山上“长”满了韩国人?周杰伦一审败诉网易房客欠租失踪 房东直发愁男子持台球杆殴打2名女店员被抓男子被猫抓伤后确诊“猫抓病”“重生之我在北大当嫡校长”槽头肉企业被曝光前生意红火男孩8年未见母亲被告知被遗忘恒大被罚41.75亿到底怎么缴网友洛杉矶偶遇贾玲杨倩无缘巴黎奥运张立群任西安交通大学校长黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发妈妈回应孩子在校撞护栏坠楼考生莫言也上北大硕士复试名单了韩国首次吊销离岗医生执照奥巴马现身唐宁街 黑色着装引猜测沈阳一轿车冲入人行道致3死2伤阿根廷将发行1万与2万面值的纸币外国人感慨凌晨的中国很安全男子被流浪猫绊倒 投喂者赔24万手机成瘾是影响睡眠质量重要因素春分“立蛋”成功率更高?胖东来员工每周单休无小长假“开封王婆”爆火:促成四五十对专家建议不必谈骨泥色变浙江一高校内汽车冲撞行人 多人受伤许家印被限制高消费