JavaScript实现计算器方法拓展
一、最终效果
由于主要是逻辑的实现,就没有过多的样式,效果图如下
HTML代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<div id="calculator"> <p> <input type="text" class="formerInput" value="1" /> <span class="sign">+</span> <input type="text" class="laterInput" value="1" /> <span>=</span> <span class="resultOutput">2</span> </p> <p> <!-- <input type="button" value="+" onclick="addHandler();" /> <input type="button" value="-" onclick="subtractHandler();" /> <input type="button" value="×" onclick="multiplyHandler();" /> <input type="button" value="÷" onclick="divideHandler();" /> --> <input type="button" value="+" class="btn" title="add" /> <input type="button" value="-" class="btn" title="subtract" /> <input type="button" value="×" class="btn" title="multiply" /> <input type="button" value="÷" class="btn" title="divide" /> <input type="button" value="%" class="btn" title="mod" /> <input type="button" value="^" class="btn" title="power" /> <input type="button" value="1/x" class="btn" title="invert" /> </p> </div> |
二、Js代码实现
0x1 最容易实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<br />// 获取元素 var calculator = document.querySelector('#calculator'); var formerInput = calculator.querySelector('.formerInput'); var laterInput = calculator.querySelector('.laterInput'); var sign = calculator.querySelector('.sign'); var resultOutput = calculator.querySelector('.resultOutput'); // 加 function addHandler() { sign.innerHTML = '+'; //前面的加号是为了将字符串转换为数字 resultOutput.innerHTML = +formerInput.value + +laterInput.value; } // 减 function subtractHandler() { sign.innerHTML = '-'; //减法不用将字符串转换为数字,直接运算 resultOutput.innerHTML = formerInput.value - laterInput.value; } // 乘 function multiplyHandler() { sign.innerHTML = '×'; resultOutput.innerHTML = formerInput.value * laterInput.value; } // 除 function divideHandler() { sign.innerHTML = '÷'; resultOutput.innerHTML = formerInput.value / laterInput.value; } |
0x2 结构和行为分离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
//HTML结构改变,行为与结构分离,删除onclick时间,统一加上btn类。 <input type="button" value="+" class="btn" /> <input type="button" value="-" class="btn" /> <input type="button" value="×" class="btn" /> <input type="button" value="÷" class="btn" /> //JavaScript代码 // 获取元素 var calculator = document.querySelector('#calculator'); var formerInput = calculator.querySelector('.formerInput'); var laterInput = calculator.querySelector('.laterInput'); var sign = calculator.querySelector('.sign'); var resultOutput = calculator.querySelector('.resultOutput'); //这里querySelectorAll() 方法返回文档中匹配指定 CSS 选择器的所有元素,返回 NodeList 对象。NodeList 对象表示节点的集合。可以通过索引访问,索引值从 0 开始。 var btns = calculator.querySelectorAll('.btn'); // 绑定事件 // + btns[0].onclick = addHandler; //绑定函数名,不要带括号表示执行。 // - btns[1].onclick = subtractHandler; // × btns[2].onclick = multiplyHandler; // ÷ btns[3].onclick = divideHandler; // 加 function addHandler() { sign.innerHTML = '+'; resultOutput.innerHTML = +formerInput.value + +laterInput.value; } // 减 function subtractHandler() { sign.innerHTML = '-'; resultOutput.innerHTML = formerInput.value - laterInput.value; } // 乘 function multiplyHandler() { sign.innerHTML = '×'; resultOutput.innerHTML = formerInput.value * laterInput.value; } // 除 function divideHandler() { sign.innerHTML = '÷'; resultOutput.innerHTML = formerInput.value / laterInput.value; } |
0x3 循环结构
主要对上一段代码中绑定事件做优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
//增加title更加语义化。 <input type="button" value="+" class="btn" title="add" /> <input type="button" value="-" class="btn" title="subtract" /> <input type="button" value="×" class="btn" title="multiply" /> <input type="button" value="÷" class="btn" title="divide" /> //JavaScript代码,仅对绑定事件优化 //绑定事件,通过循环结构绑定事件 for (var i = 0; i < btns.length; i++) { btns[i].onclick = function () { switch (this.title) { case 'add': addHandler(); break; case 'subtract': subtractHandler(); break; case 'multiply': multiplyHandler(); break; case 'divide': divideHandler(); break; } }; } |
0x4 函数提取
不希望代码暴露过多的细节,可以利用函数封装代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
//JavaScript代码 //获取元素部分不变 //绑定事件 each(btns, function (index, elem) { elem.onclick = function () { switch (this.title) { case 'add': addHandler(); break; case 'subtract': subtractHandler(); break; case 'multiply': multiplyHandler(); break; case 'divide': divideHandler(); break; } }; }); // 遍历 function each(array, fn) { for (var i = 0; i < array.length; i++) { fn(i, array[i]); } } // 更新符号 function updateSign(symbol) { sign.innerHTML = symbol; } // 加法 function add(num1, num2) { return +num1 + +num2; } // 减法 function subtract(num1, num2) { return num1 - num2; } // 乘法 function multiply(num1, num2) { return num1 * num2; } // 除法 function divide(num1, num2) { return num1 / num2; } // 输出结果 function outputResult(result) { resultOutput.innerHTML = result; } // 加 function addHandler() { // sign.innerHTML = '+'; updateSign('+'); outputResult(add(formerInput.value, laterInput.value)); } // 减 function subtractHandler() { updateSign('-'); outputResult(subtract(formerInput.value, laterInput.value)); } // 乘 function multiplyHandler() { updateSign('×'); outputResult(multiply(formerInput.value, laterInput.value)); } // 除 function divideHandler() { updateSign('÷'); outputResult(divide(formerInput.value, laterInput.value)); } |
0x5 管理代码
上一段代码中,获取元素的一部分比较繁琐,改进之
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// 获取元素 var wrapElem = document.querySelector('#calculator'); var calculatorElem = { formerInput: wrapElem.querySelector('.formerInput'), laterInput: wrapElem.querySelector('.laterInput'), sign: wrapElem.querySelector('.sign'), resultOutput: wrapElem.querySelector('.resultOutput'), btns: wrapElem.querySelectorAll('.btn') }; // 绑定事件 each(calculatorElem.btns, function (index, elem) { elem.onclick = function () { switch (this.title) { case 'add': addHandler(); break; case 'subtract': subtractHandler(); break; case 'multiply': multiplyHandler(); break; case 'divide': divideHandler(); break; } }; }); //下面做相应改变 |
0x6 封闭原则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
获取元素 var wrapElem = document.querySelector('#calculator'); var calculatorElem = { formerInput: wrapElem.querySelector('.formerInput'), laterInput: wrapElem.querySelector('.laterInput'), sign: wrapElem.querySelector('.sign'), resultOutput: wrapElem.querySelector('.resultOutput'), btns: wrapElem.querySelectorAll('.btn') }; // 绑定事件 each(calculatorElem.btns, function (index, elem) { elem.onclick = function () { updateSign(this.value); outputResult(operate(this.title, calculatorElem.formerInput.value, calculatorElem.laterInput.value)); }; }); // 遍历 function each(array, fn) { for (var i = 0; i < array.length; i++) { fn(i, array[i]); } } // 更新符号 function updateSign(symbol) { calculatorElem.sign.innerHTML = symbol; } // 运算 function operate(name, num1, num2) { if (!operation[name]) throw new Error('不存在名为' + name + '的运算方法!'); return operation[name](num1, num2); } var operation = { add: function (num1, num2) { return +num1 + +num2; }, subtract: function (num1, num2) { return num1 - num2; }, multiply: function (num1, num2) { return num1 * num2; }, divide: function (num1, num2) { return num1 / num2; }, addOperation: function (name, fn) { if (!this[name]) { this[name] = fn; } return this; } }; operation.addOperation('mod', function (num1, num2) { return num1 % num2; }).addOperation('power', function (base, power) { return Math.pow(base, power); }); // 输出结果 function outputResult(result) { calculatorElem.resultOutput.innerHTML = result; } |