前端使用 JavaScript 实现一个简易计算器,没有难度,但是里面有些小知识还是需要注意的,算是一次基础知识回顾吧。

题目

计算器

实现一个简易版的计算器,需求如下:

1、除法操作时,如果被除数为0,则结果为0
2、结果如果为小数,最多保留小数点后两位,如 2 / 3 = 0.67(显示0.67), 1 / 2 = 0.5(显示0.5)
3、请阅读并根据提示补充完成函数initEvent、result和calculate
4、请不要手动修改html和css
5、不要使用第三方插件

实现

HTML 文件

  1. <div class="calculator">
  2. <header class="cal-header">简易计算器</header>
  3. <main class="cal-main">
  4. <div class="origin-value">0</div>
  5. <div class="cal-keyboard">
  6. <ul class="cal-items">
  7. <li data-action="num">7</li>
  8. <li data-action="num">8</li>
  9. <li data-action="num">9</li>
  10. <li data-action="operator">÷</li>
  11. <li data-action="num">4</li>
  12. <li data-action="num">5</li>
  13. <li data-action="num">6</li>
  14. <li data-action="operator">x</li>
  15. <li data-action="num">1</li>
  16. <li data-action="num">2</li>
  17. <li data-action="num">3</li>
  18. <li data-action="operator">-</li>
  19. <li data-action="num">0</li>
  20. <li data-action="operator">清空</li>
  21. <li data-action="operator">=</li>
  22. <li data-action="operator">+</li>
  23. </ul>
  24. </div>
  25. </main>
  26. </div>

CSS 文件

  1. body, ul, li,select {
  2. margin: 0;
  3. padding: 0;
  4. box-sizing: border-box;
  5. }
  6. ul,li {list-style: none;}
  7. .calculator {
  8. max-width: 300px;
  9. margin: 20px auto;
  10. border: 1px solid #eee;
  11. border-radius: 3px;
  12. }
  13. .cal-header {
  14. font-size: 16px;
  15. color: #333;
  16. font-weight: bold;
  17. height: 48px;
  18. line-height: 48px;
  19. border-bottom: 1px solid #eee;
  20. text-align: center;
  21. }
  22. .cal-main {
  23. font-size: 14px;
  24. }
  25. .cal-main .origin-value {
  26. padding: 15px;
  27. height: 40px;
  28. line-height: 40px;
  29. font-size: 20px;
  30. text-align: right;
  31. overflow: hidden;
  32. text-overflow:ellipsis;
  33. white-space: nowrap;
  34. }
  35. .cal-main .origin-type,
  36. .cal-main .target-type {
  37. padding-left: 5px;
  38. width: 70px;
  39. font-size: 14px;
  40. height: 30px;
  41. border: 1px solid #eee;
  42. background-color: #fff;
  43. vertical-align: middle;
  44. margin-right: 10px;
  45. border-radius: 3px;
  46. }
  47. .cal-keyboard {
  48. overflow: hidden;
  49. }
  50. .cal-items {
  51. overflow: hidden;
  52. }
  53. .cal-items li {
  54. user-select: none;
  55. float: left;
  56. display: inline-block;
  57. width: 75px;
  58. height: 75px;
  59. text-align: center;
  60. line-height: 75px;
  61. border-top: 1px solid #eee;
  62. border-left: 1px solid #eee;
  63. box-sizing: border-box;
  64. }
  65. li:nth-of-type(4n+1) {
  66. border-left: none;
  67. }
  68. li[data-action=operator] {
  69. background: #f5923e;
  70. color: #fff;
  71. }
  72. .buttons {
  73. float: left;
  74. width: 75px;
  75. }
  76. .buttons .btn {
  77. width: 75px;
  78. background-color: #fff;
  79. border-top: 1px solid #eee;
  80. border-left: 1px solid #eee;
  81. height: 150px;
  82. line-height: 150px;
  83. text-align: center;
  84. }
  85. .btn-esc {
  86. color: #ff5a34;
  87. }
  88. .btn-backspace {
  89. position: relative;
  90. }

JavaScript 文件

  1. var Calculator = {
  2. init: function () {
  3. var that = this;
  4. if (!that.isInited) {
  5. that.isInited = true;
  6. // 保存操作信息
  7. // total: Number, 总的结果
  8. // next: String, 下一个和 total 进行运算的数据
  9. // action: String, 操作符号
  10. that.data = {total: 0, next: '', action: ''};
  11. that.bindEvent();
  12. }
  13. },
  14. bindEvent: function () {
  15. var that = this;
  16. // 获取 .cal-keyboard 元素
  17. var keyboardEl = document.querySelector(".cal-keyboard");
  18. keyboardEl && keyboardEl.addEventListener('click', function (event) {
  19. // 获取当前点击的dom元素
  20. var target = event.target;
  21. // 获取target的 data-action 值
  22. var action = target.dataset.action;
  23. // 获取target的内容
  24. var value = target.innerText;
  25. if (action === 'num' || action === 'operator') {
  26. that.result(value, action === 'num');
  27. }
  28. });
  29. },
  30. result: function (action, isNum) {
  31. var that = this;
  32. var data = that.data;
  33. if (isNum) {
  34. data.next = data.next === '0' ? action : (data.next + action);
  35. !data.action && (data.total = 0);
  36. } else if (action === '清空') {
  37. // 设置清空时的对应状态
  38. data.total = 0;
  39. data.next = "";
  40. data.action = "";
  41. } else if (action === '=') {
  42. if (data.next || data.action) {
  43. data.total = that.calculate(data.total, data.next, data.action);
  44. data.next = '';
  45. data.action = '';
  46. }
  47. } else if (!data.next) {
  48. data.action = action;
  49. } else if (data.action) {
  50. data.total = that.calculate(data.total, data.next, data.action);
  51. data.next = '';
  52. data.action = action;
  53. } else {
  54. data.total = +data.next || 0;
  55. data.next = '';
  56. data.action = action;
  57. }
  58. // 获取 .origin-value 元素
  59. var valEl = document.querySelector(".origin-value");
  60. // print(data)
  61. valEl && (valEl.innerHTML = data.next || data.total || '0');
  62. },
  63. calculate: function (n1, n2, operator) {
  64. n1 = +n1 || 0;
  65. n2 = +n2 || 0;
  66. if (operator === '÷') {
  67. // 获取除法的结果
  68. return n2 === 0 ? 0 : Math.floor((n1 / n2) * 100) / 100;
  69. } else if (operator === 'x') {
  70. // 获取乘法的结果
  71. return Math.floor((n1 * n2) * 100) / 100;
  72. } else if (operator === '+') {
  73. // 获取加法的结果
  74. return Math.floor((n1 + n2) * 100) / 100;
  75. } else if (operator === '-') {
  76. // 获取减法的结果
  77. return Math.floor((n1 - n2) * 100) / 100;
  78. }
  79. }
  80. };
  81. Calculator.init();

分析

主要分析一下本题中 JavaScript 部分涉及的知识点。

事件委托

我们没有给数字和符号元素分别添加点击事件,而是通过给它们的父元素 .cal-keyboard 添加点击事件,再通过事件冒泡获得它父元素绑定的事件响应,使用事件委托有以下优点:

  • 减少内存消耗
  • 可以方便地动态添加或者删除元素
  • 管理的函数减少
  • 减少操作 DOM 节点的次数,提高性能

事件委托的步骤:

  1. 给父元素绑定响应事件
  2. 监听子元素的冒泡事件
  3. 获取触发事件的目标元素

保留小数位

大家的第一反应可能是使用 toFixed() 方法,但是这个方法在小数位不足的情况下会在后面补 0,比如:

  1. const num = 0.8;
  2. num.toFixed(2) // 0.80

可以看到,这个是不符合要求的。

还有一个问题需要注意:小数的相加结果可能并不符合预期,比如:

  1. console.log(0.2 + 0.4) // 0.6000000000000001

这里我们建议使用 Math.floor() 方法来处理小数位,先给结果乘以 100,再通过 Math.floor() 取得整数部分,然后除以 100,得到符合要求的结果,比如:

  1. const num1 = 0.5;
  2. const num2 = 0.68751;
  3. Math.floor(num1 * 100)/100 // 0.5
  4. Math.floor(num2 * 100)/100 // 0.68

~

~ 本文完

~

学习有趣的知识,结识有趣的朋友,塑造有趣的灵魂!

大家好,我是〖编程三昧〗的作者 隐逸王,我的公众号是『编程三昧』,欢迎关注,希望大家多多指教!

你来,怀揣期望,我有墨香相迎! 你归,无论得失,唯以余韵相赠!

知识与技能并重,内力和外功兼修,理论和实践两手都要抓、两手都要硬!

更多相关文章

  1. 字体图标引用、网页布局与元素排列、盒模型使用
  2. 字体图标、布局原理一级盒模型实例操作
  3. 图标,布局,元素类型,盒子模型
  4. 字体图标、布局原理以及盒模型实例操作及思考
  5. CSS-作业
  6. 小计不重要
  7. 字体图标的使用和盒模型的理解与box-sizing解决了什么问题以及布
  8. 伪类选择器+盒模型+icon的使用方法+百分比设置元素大小
  9. 盒模型与字体图标使用

随机推荐

  1. 使用response.sendirect("html/employee.
  2. 从html文档中解析数据()[重复]
  3. 如何在离子框架中显示图像标题?
  4. CGI编程学习5 穿插HTML,CSS零星知识
  5. html5结合flash实现视频文件在所有主流浏
  6. DOM笔记(三):Element接口和HTMLElement接口
  7. [原创]基于html5新标签canvas写的一个小
  8. 大熊君学习html5系列之
  9. web前端2016-3-5
  10. iis aspx常见错误 HTTP 错误 404 - 文件