经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
原生javascript开发计算器实例
来源:cnblogs  作者:蒋伟平  时间:2021/2/22 9:04:32  对本文有异议

计算器的主要作用是进行数字运算,开发一个计算器功能的web实例,有助于更好的掌握js基础的数字运算能力。

本实例详细分析一个js计算器的开发步骤,学习本教程时最好先具备一些基础的js知识。

计算器包括显示数字区域和按键区域两大部分,先把计算器的这两个区域的html元素编写出来,如下所示:

  1. <div class="calculator_wrap" id="calculator"><!--计算器外包元素-->
  2. <div class="show_num"><!--显示数字区域-->
  3. <div class="num_save" id="numSave"></div><!--计算公式-->
  4. <div class="num_cur" id="numCur">0</div><!--计算结果-->
  5. <div class="show_m" id="showM">M</div><!--记忆存储标志-->
  6. </div>
  7. <div class="btn_wrap" id="btnWrap"><!--按钮区域-->
  8. <div class="btn" data-key="MC">MC</div><!--记忆清零-->
  9. <div class="btn" data-key="MR">MR</div><!--记忆读取-->
  10. <div class="btn" data-key="MS">MS</div><!--存储记忆-->
  11. <div class="btn" data-key="MA">M+</div><!--记忆加-->
  12. <div class="btn" data-key="ML">M-</div><!--记忆减-->
  13. <div class="btn" data-key="BACK"></div><!--退格-->
  14. <div class="btn" data-key="CE">CE</div><!--清除当前-->
  15. <div class="btn" data-key="Clear">C</div><!--清除-->
  16. <div class="btn" data-key="Negate">±</div><!--正负转换-->
  17. <div class="btn" data-key="Square">√ ̄</div><!--平方根-->
  18. <div class="btn" data-key="Num" data-value="7">7</div><!--7-->
  19. <div class="btn" data-key="Num" data-value="8">8</div><!--8-->
  20. <div class="btn" data-key="Num" data-value="9">9</div><!--9-->
  21. <div class="btn" data-key="Base" data-value="/">/</div><!---->
  22. <div class="btn" data-key="Percentage">%</div><!--百分号-->
  23. <div class="btn" data-key="Num" data-value="4">4</div><!--4-->
  24. <div class="btn" data-key="Num" data-value="5">5</div><!--5-->
  25. <div class="btn" data-key="Num" data-value="6">6</div><!--6-->
  26. <div class="btn" data-key="Base" data-value="*">*</div><!---->
  27. <div class="btn" data-key="Reciprocal">1/x</div> <!--倒数-->
  28. <div class="btn" data-key="Num" data-value="1">1</div><!--1-->
  29. <div class="btn" data-key="Num" data-value="2">2</div><!--2-->
  30. <div class="btn" data-key="Num" data-value="3">3</div><!--3-->
  31. <div class="btn" data-key="Base" data-value="-">-</div><!---->
  32. <div class="btn equal" data-key="Equal">=</div><!--等于-->
  33. <div class="btn zero" data-key="Num" data-value="0">0</div><!--0-->
  34. <div class="btn" data-key="Point">.</div><!--小数点-->
  35. <div class="btn" data-key="Base" data-value="+">+</div><!---->
  36. </div>
  37. </div>

读者可以自己编写一些样式,设计一个自己喜欢的计算器效果。本实例的计算器效果如下图所示:

 

样式代码:

  1. .calculator_wrap{width:240px;height:360px;padding:10px;margin:30px auto;border:1px solid #8acceb;background:#d1f1ff;}
  2. .calculator_wrap .show_num{position:relative;padding:0 8px;height:60px;background:#fff;text-align:right;}
  3. .calculator_wrap .show_m{position: absolute;left:10px;bottom:3px;display:none;}
  4. .calculator_wrap .num_save{height:26px;line-height:26px;font-size:12px;white-space:nowrap;}
  5. .calculator_wrap .num_cur{font-size:28px;height:34px;line-height:34px;}
  6. .calculator_wrap .btn_wrap{font-size:0px;}
  7. .calculator_wrap .btn{display:inline-block;width:38px;height:38px;line-height:38px;text-align:center;border:1px solid #ccc;background:#666;color:#fff;font-size:14px;margin:10px 10px 0 0;cursor:pointer;}
  8. .calculator_wrap .btn:hover{background:#333;}
  9. .calculator_wrap .btn:nth-child(5n){margin-right:0px;}
  10. .calculator_wrap .equal{position:absolute;height:90px;line-height:90px;}
  11. .calculator_wrap .zero{width:90px;}

 

对于新手来说,计算器功能看起来好像很复杂,那么多按钮、多种计算方式,不知如何开始。其实任何一个功能,只需要理清楚思路,一步一步编写代码,会发现实现起来都不难。

 

1 获取各个html元素

web前端不论要在页面上做什么,都要先获取页面上的各个DOM元素。看起来整个计算器的按钮较多,实际开发中可以使用事件代理来操作按钮,所以只获取所有按钮的容器元素即可。代码如下:

  1. //获取外包元素
  2. var eCalculator = document.getElementById('calculator');
  3. //保存运算数据(公式)容器
  4. var eNumSave = document.getElementById('numSave');
  5. //当前数字容器
  6. var eNumCur = document.getElementById('numCur');
  7. //按钮外部容器,用于事件代理
  8. var eBtnWrap = document.getElementById('btnWrap');
  9. //记忆存储标志元素
  10. var eShowM = document.getElementById('showM');

 

2 声明相关变量

在运算过程中,需要一些变量来进行辅助计算、存储结果和判断等,如下所示:

  1. //运算公式
  2. var sStep = '';
  3. //当前数字
  4. var sCurValue = '0';
  5. //运算结果
  6. var nResult = null;
  7. //运算符
  8. var sMark = '';
  9. //MR记忆存储数据
  10. var nMvalue = 0;
  11. //输入状态。false:输入数字替换原数字;true:输入数字加到原数字后面;
  12. var bLogStatus = false;

 

3 按键上添加点击事件

因为整个计算器按键较多,每一个按钮都单独绑定一个事件会显得太多,很繁琐,还会影响性能,且容易出错。所以刚才只获取了按键的外部容器 eCalculator。

再使用事件代理,就只需要在容器上添加点击事件,判断当前点击的按键是哪一个,再执行对应的计算即可。用鼠标点击按键的时候,可能会因为点得太快而选择了按键上的文字,因此还需要在外包容器上添加一个阻止默认行为的操作,代码如下所示:

  1. //外包容器添加鼠标按下事件,用于防止选中文字
  2. eCalculator.addEventListener('mousedown',function(event){
  3. //阻止鼠标按下时的默认行为,防止点击按钮过快时选中文字
  4. event.preventDefault();
  5. });
  6. //按键容器添加点击事件,用于代理所有按键的操作
  7. eBtnWrap.addEventListener('click',function(event){
  8. });

3.1 获取点击的按键和值

通过事件函数传入的event参数,可以获取到鼠标点击的元素。再通过元素上的data-key和data-value属性判断鼠标点击的是哪一个按键以及它的值,如下所示:

  1. eBtnWrap.addEventListener('click',function(event){
  2. //获取点击的元素
  3. var eTarget = event.target;
  4. //判断按下的键
  5. var key = eTarget.dataset.key;
  6. //获取按下的值
  7. var value = eTarget.dataset.value;
  8. });

3.2 判断按键及值,数字键和小数点执行输入操作

如果按键属性data-key是'Num'表示按下的是数字,'Point'表示小数点。

这些按键都是执行输入,因为数字有多个,所以把数字输入封装到fnInputNum函数中。再封装fnShowResult函数把数据显示到显示数字区域。如下所示:

  1. eBtnWrap.addEventListener('click',function(event){
  2. /**/
  3.  
  4. //判断点击的是否是按键
  5. if(key){
  6. //用switch语句判断不同的按键执行对应的操作
  7. switch(key){
  8. //数字键执行操作
  9. case 'Num':
  10. fnInputNum(value);
  11. break;
  12. //小数点操作
  13. case 'Point':
  14. //判断是否有已小数点,用于限制只能输入一个小数点
  15. if(sCurValue.indexOf('.')==-1){
  16. sCurValue = sCurValue + '.';
  17. bLogStatus = true;
  18. }
  19. break;
  20. }
  21. //显示数据到显示数字区域
  22. fnShowResult();
  23. }
  24. });
  25. //输入数字
  26. function fnInputNum(num){
  27. //根据输入状态判断是替换当前数字还是添加到当前数字后面
  28. if(bLogStatus){
  29. sCurValue = sCurValue + num;
  30. }else{
  31. //限制第一个数字不能是0
  32. if(num!=0){
  33. bLogStatus = true;
  34. }
  35. sCurValue = num;
  36. }
  37. }
  38. //显示计算结果
  39. function fnShowResult(){
  40. //显示计算公式
  41. eNumSave.innerHTML = sStep;
  42. //限制数字总长度
  43. if(sCurValue.length>14){
  44. sCurValue = sCurValue.slice(0,14);
  45. }
  46. //显示当前数字
  47. eNumCur.innerHTML = sCurValue;
  48. }

这时候已经可以点击数字和小数点,输入到计算器显示屏上,如图所示:

  

3.3 加减乘除运算

计算器最基本的就是加减乘除运算。为了实现对数字进行加减乘除并计算结果功能,封装fnCountResult、fnBaseCount和fnEqual三个函数。

fnCountResult用于根据运算符计算结果;

fnBaseCount修改计算公式或计算结果;

fnEqual用于按下=号时计算结果,并重置数据。如下所示:

  1. eBtnWrap.addEventListener('click',function(event){
  2. /**/
  3.  
  4. //判断点击的是否是按键
  5. if(key){
  6. //用switch语句判断不同的按键执行对应的操作
  7. switch(key){
  8. /**/
  9. //加减乘除基本运算
  10. case 'Base':
  11. fnBaseCount(value);
  12. break;
  13. //等于
  14. case 'Equal':
  15. fnEqual();
  16. break;
  17. }
  18. //显示数据到显示数字区域
  19. fnShowResult();
  20. }
  21. });
  22. //计算结果
  23. function fnCountResult(){
  24. //判断当前运算符并执行运算
  25. switch(sMark){
  26. case '+':
  27. nResult = nResult===null?+sCurValue:nResult + (+sCurValue);
  28. break;
  29. case '-':
  30. nResult = nResult===null?+sCurValue:nResult - sCurValue;
  31. break;
  32. case '*':
  33. nResult = nResult===null?+sCurValue:nResult * sCurValue;
  34. break;
  35. case '/':
  36. nResult = nResult===null?+sCurValue:nResult / sCurValue;
  37. break;
  38. default:
  39. nResult = +sCurValue;
  40. }
  41. }
  42. //加减乘除基础运算
  43. function fnBaseCount(key){
  44. //如果是输入状态,进行运算
  45. if(bLogStatus){
  46. //修改输入状态
  47. bLogStatus = false;
  48. //计算公式
  49. sStep = sStep + ' ' + sCurValue + ' ' + key;
  50. //计算结果
  51. fnCountResult();
  52. sCurValue = ''+nResult;
  53. }else{
  54. //如果公式为空,先加上原始数字
  55. if(sStep==''){
  56. sStep = sCurValue + ' ' + key;
  57. }else{ //如果已有公式,更改最后的运算符
  58. sStep = sStep.slice(0,sStep.length-1) + ' ' + key;
  59. }
  60. }
  61. //更改运算符,用于计算
  62. sMark = key;
  63. }
  64. //等于
  65. function fnEqual(){
  66. //如果没有运算符,阻止后续操作
  67. if(sMark=='')return;
  68. //计算结果
  69. fnCountResult();
  70. sCurValue = ''+nResult;
  71. //重置数据
  72. sStep = '';
  73. sMark = '';
  74. bLogStatus = false;
  75. }

现在已经可以在计算器上做加减乘除的计算了,如图所示:

 

3.4 再给其他按键添加操作,代码如下所示:

  1. eBtnWrap.addEventListener('click',function(event){
  2. /**/
  3.  
  4. //判断点击的是否是按键
  5. if(key){
  6. //用switch语句判断不同的按键执行对应的操作
  7. switch(key){
  8. /**/
  9.  
  10. //清除
  11. case 'Clear':
  12. fnClear()
  13. break;
  14. //退格
  15. case 'BACK':
  16. fnBack();
  17. break;
  18. //CE
  19. case 'CE':
  20. //清空当前显示数值
  21. sCurValue = '0';
  22. bLogStatus = false;
  23. break;
  24. //取反
  25. case 'Negate':
  26. //当前数值取反
  27. sCurValue = ''+(-sCurValue);
  28. break;
  29. //取平方根
  30. case 'Square':
  31. //当前数值取平方根
  32. nResult = Math.sqrt(+sCurValue);
  33. //其他数据初始化
  34. sCurValue = ''+nResult;
  35. sStep = '';
  36. sMark = '';
  37. bLogStatus = false;
  38. break;
  39. //倒数
  40. case 'Reciprocal':
  41. //当前数值取倒数
  42. //其他数据初始化
  43. nResult = 1/sCurValue;
  44. sCurValue = ''+nResult;
  45. sStep = '';
  46. sMark = '';
  47. bLogStatus = false;
  48. break;
  49. //M系列
  50. case 'MC':
  51. //记忆数值清零
  52. nMvalue = 0;
  53. fnShowM()
  54. break;
  55. case 'MR':
  56. //显示记忆数值
  57. sCurValue = '' + nMvalue;
  58. fnShowM()
  59. break;
  60. case 'MS':
  61. //记忆数值改为当前数值
  62. nMvalue = +sCurValue;
  63. fnShowM()
  64. break;
  65. case 'MA':
  66. //当前数值加到记忆数值中
  67. nMvalue += +sCurValue;
  68. fnShowM()
  69. break;
  70. case 'ML':
  71. //从记忆数值中减去当前数值
  72. nMvalue -= +sCurValue;
  73. fnShowM()
  74. break;
  75. }
  76. //显示数据到显示数字区域
  77. fnShowResult();
  78. }
  79. });
  80. //清除
  81. function fnClear(){
  82. //初始化所有数据
  83. sStep = '';
  84. sCurValue = '0';
  85. nResult = null;
  86. sMark = '';
  87. bLogStatus = false;
  88. }
  89. //退格
  90. function fnBack(){
  91. //必须是输入状态才可以退格
  92. if(bLogStatus){
  93. //减去数值最后一位数
  94. sCurValue = sCurValue.slice(0,sCurValue.length-1);
  95. //如果最后数值为空或负号(-),改为0,重置输入状态为false,不可再退格
  96. if(sCurValue==''||sCurValue=='-'){
  97. sCurValue = '0';
  98. bLogStatus = false;
  99. }
  100. }
  101. }
  102. //判断是否有M记忆存储
  103. function fnShowM(){
  104. bLogStatus = false;
  105. //判断是否显示记忆存储标志
  106. eShowM.style.display = nMvalue==0?'none':'block';
  107. }

 

4 绑定键盘事件
写到这里,计算器已经可以正常使用了。不过只能用鼠标点击按键操作效率不高,为了可以更快的使用计算器,还需要加上键盘事件,当按下对应按键时,执行操作,如下所示:

  1. //键盘事件
  2. document.addEventListener('keyup',function(event){
  3. //获取当前键盘按键
  4. var key = event.key;
  5. //获取按键code
  6. var code = event.keyCode;
  7. //限制正确的按键才修改显示的数据
  8. var comply = false;
  9. //输入数字
  10. if((code>=48&&code<=57)||(code>=96&&code<=105)){
  11. fnInputNum(key);
  12. comply = true;
  13. }
  14. //加减乘除
  15. if( key=='*'||key=='+'||key=='/'||key=='-'){
  16. fnBaseCount(key);
  17. comply = true;
  18. }
  19. //esc键
  20. if(code==27){
  21. fnClear();
  22. comply = true;
  23. }
  24. //回车键
  25. if(code==13){
  26. fnEqual();
  27. comply = true;
  28. }
  29. //退格键
  30. if(code==8){
  31. fnBack();
  32. comply = true;
  33. }
  34. if(comply){
  35. //显示数据到计算器屏幕
  36. fnShowResult();
  37. }
  38. });

 

一个简单的计算器就完成了,如果以学习为目的话,建议不要直接复制代码,最好直接手动输入代码及注释,加深印象和提高学习效果。

原文链接:http://www.cnblogs.com/jiangweiping/p/14418393.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号