###### tags: `JavaScript` # Calculator 計算機攻略 [程式碼 CodePen](https://codepen.io/enzoLuo/pen/jOrjBKP) ## 目標 1. 能做簡單四則運算 2. 可以使用鍵盤做操作 3. 數字位數過多處理 4. 功能按鍵 ## UI 參考範本: IOS計算機 ![](https://i.imgur.com/wK8NM13.png) 上半圖數字的 info 區塊, 下半部按鍵的 keypad 區塊 keypad 區塊分兩種按鍵 數字按鍵及功能按鍵 * 資訊顯示 1. 數值顯示 () 2. operator (x, +, - ...etc) 3. status (overflow, full) * 功能按鍵 1. +, -, x, ÷, = 2. C, +-, %, . * 數字按鍵 1. Number 0~9 ## 設計想法 將計算機用物件包裝起來 ```javascript= const calculator = { value: 0, // 儲存目前的值(基本上與計算機中的值一樣) operator: '', // 存放運算子, 點選加減乘除會放進來並更新畫面右上角, 提醒目前的運算) valueTemp: 0, // 使用運算子後會把原本的 value存放過來, 用來計算用, 使用'='後清空 isFullSize: false, // 數字位數是否過多? 為true時無法輸入並顯示在左上角資訊 isOverFlow: false, // 是否溢位, 如果計算結果為 e+ 科學記號時觸發, 並無法再計算 renderValue(value) {}, // 渲染畫面 value 位置的 function renderOperator(operator) {}, // 渲染畫面 operator資訊的 function checkInfoSize(len) {}, // 檢查目前畫面是否滿了, 並更新 isFullSize 值 renderBool() {}, // 將目前 isFullSize 及 isOverFlow 渲染到畫面上 funcNumKey(keyValue) {}, // 使用數字按鍵觸發的 function funcOperatorKey(keyValue) {}, // 使用功能按鍵觸發的 function } ``` ## 功能需求 ### 數字按鍵 1. 1~9 可以直接對value相加, 要注意的是要字串相加並非數字相加 2. 為0的時候, 輸入0應該使其無法輸入直接 reject ### 基本運算(加減乘除) 原本的做法如下, 後來看到有人利用 eval()函式並試著使用, eval可以自動把字串轉換並返回計算結果 ```javascript= function count() { switch (opTemp) { case '+': infoEl.textContent = numTemp + Number(infoEl.textContent); break; case '-': infoEl.textContent = numTemp - Number(infoEl.textContent); break; case 'x': infoEl.textContent = numTemp * Number(infoEl.textContent); break; case '÷': infoEl.textContent = (numTemp / Number(infoEl.textContent)).toFixed(2); break; } } ``` 使用 eval(); ```javascript= let result = String(eval(`${this.valueTemp}${operator}${this.value}`)); ``` ### 特殊功能 1. AC 功能 * 清除所有的value, operator, 暫存, 所有狀態 並恢復成0 2. +- 功能 * 如果 value 為 0 不具效果 3. % 功能 * 每次除 100 並返回, 如果最後 0.00 使其下一動為 0 4. 小數點('.') 功能 * 如果已經有小數點不具作用 ### 數字位數過多時處理 利用字串長度判斷數字位數是否過多, 並依照目前的數字位數給予不同的字體大小, 最後超過令使用者無法輸入 ```javascript= checkInfoSize(len) { let valueLen = String(this.value).length; if(valueLen < 7) { infoValue.style['font-size'] = '80px'; this.isFullSize = false; } else if (valueLen < 9) { infoValue.style['font-size'] = '65px'; this.isFullSize = false; } else if (valueLen < 11) { infoValue.style['font-size'] = '50px'; this.isFullSize = false; } else if (valueLen < 14) { infoValue.style['font-size'] = '36px'; this.isFullSize = false; } else if (valueLen < 19) { infoValue.style['font-size'] = '30px'; this.isFullSize = false; } else { this.isFullSize = true; } } ```