草圖

功能需求
- 點擊數字按鈕輸入數字
- 點擊符號按鈕進行計算
- 清除功能
需求功能分析
- 判斷數字
- 判斷符號
- 數字與符號進行計算
- 記憶前一個數字
- 清除
使用工具
- jQuery 3.x
- Bootstrap 4
實作 UI
採用 Bootstrap 4 加速 UI 實作。
先將整體計算機外觀勾勒出來。
<div class="container">
<h2>計算機小工具</h2>
<hr>
<div class="alert alert-info text-right pr-3 d-flex justify-content-end align-items-center" id="result">
<div id="total">0</div>
<div id="operator"></div>
</div>
<div class="row" id="number-area">
<div class="col-3 number-button">C</div>
<div class="col-3 number-button">+/-</div>
<div class="col-3 number-button">%</div>
<div class="col-3 number-button">/</div>
<div class="col-3 number-button">7</div>
<div class="col-3 number-button">8</div>
<div class="col-3 number-button">9</div>
<div class="col-3 number-button">x</div>
<div class="col-3 number-button">4</div>
<div class="col-3 number-button">5</div>
<div class="col-3 number-button">6</div>
<div class="col-3 number-button">-</div>
<div class="col-3 number-button">1</div>
<div class="col-3 number-button">2</div>
<div class="col-3 number-button">3</div>
<div class="col-3 number-button">+</div>
<div class="col-6 number-button">0</div>
<div class="col-3 number-button">.</div>
<div class="col-3 number-button">=</div>
</div>
</div>
再針對 CSS 動些手腳。
<style>
#result {
height: 100px;
font-size: 3rem;
margin: 0;
border-radius: 0;
}
#operator {
width: 50px;
}
#number-area {
margin: 0;
}
#number-area>div {
border: 1px solid #f2f1f1;
cursor: pointer;
}
#number-area>div:hover {
background: #f45f29;
color: #fff;
font-size: 1.5rem;
transition: .3s;
}
.number-button {
display: flex;
justify-content: center;
align-items: center;
height: 50px;
background: #dedede;
}
@media screen and (max-width: 765px) {
#result {
font-size: 1.5rem;
}
}
</style>

整體的 UI 呈現就告一段落。
實作程式
建立一個物件,來表示計算機。
const calc = {
}
接下來回顧一下需要的功能。
- 判斷數字
- 判斷符號
- 數字與符號進行計算
- 記憶前一個數字
- 清除
根據這些功能,先把 method 定義出來。
const calc = {
isNumber(value) {
},
isOperator(value) {
},
calc() {
},
savePreNum(value) {
},
reset() {
}
}
接下來,可能需要幾個屬性來做紀錄。
const calc = {
prevNum: '',
num: 0,
operator: '',
... methods
}
整體物件部署完成,接著要做事件綁定。
const calc = {
init() {
$('#number-area > .number-button').on('click', (e) => {
let value = $(e.target).html();
this.isOperator(value);
this.isNumber(value);
});
},
}
calc.init();
判斷數字 isNumber
isNumber(value) {
if (!/^\d$/.test(value) && value != '.') {
return false;
}
if (value == '.' && /\./.test(this.num)) {
return false;
}
this.num += value;
this.num = this.num.replace(/^0+/, '');
this.total(this.num);
},
數字基本上就是 0 ~ 9,所以用一個 regular 來過濾即可,但是也要能接受小數點的符號,所以連同小數點也進入第一個判斷。
一個數字的小數點只有一個,所以應該針對小數點做些過濾。
後面就是做字串相加跟一些取代,然後呈現到指定的 DOM 內。
判斷符號 isOperator
operators: ['+', '-', 'x', '%', '/'],
isOperator(value) {
if (this.operators.indexOf(value) >= 0) {
this.operator = value;
$('#operator').html(value);
if (!this.prevNum) {
this.prevNum = this.num;
}
this.num = 0;
}
if (value == '+/-') {
let num = this.prevNum || this.num;
num *= -1;
this.total(num);
this.num = num;
}
if (value == 'C') {
this.prevNum = '';
this.num = 0;
this.total(0);
this.operator = '';
$('#operator').html('');
}
if (value == '=') {
this.calc();
}
},
因為可以運算的符號是可以列出來的,所以用一陣列來管理,後面只需要用 indexOf 來判斷是否有在陣列內。
計算 calc
calc() {
if (!this.operator) {
return false;
}
let total = 0;
let a = parseFloat(this.prevNum);
let b = parseFloat(this.num);
switch (this.operator) {
case '+':
total = a + b;
break;
case '-':
total = a - b;
break;
case 'x':
total = a * b;
break;
case '/':
total = a / b;
break;
case '%':
total = a % b;
break;
}
total = Math.round(total * 100) / 100; // 小數兩位
this.total(total);
this.prevNum = total;
},
根據四則運算符號進行運算後,把最終數值顯示在頁面上,並且將計算結果跟記憶用的屬性,作為下次計算用。