前些日子呢,我們一同學習了許多有關網頁三件套 —— HTML、CSS、JS的內容。納在本日的篇章中,我將帶著您使用這幾日所學,來實作出一個計算機的應用!
完成效果:https://ttdragon0722.github.io/A-Calculator/
範例如下圖所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CALCULATOR</title>
</head>
<body>
<div class="app">
<div class="panel">
<div class="history">123</div>
<div class="output">456</div>
</div>
<button>DEL</button>
<button>/</button>
<button>*</button>
<button>-</button>
<button>7</button>
<button>8</button>
<button>9</button>
<button class="col-2">+</button>
<button>4</button>
<button>5</button>
<button>6</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button class="col-2">=</button>
<button>AC</button>
<button>0</button>
<button>.</button>
</div>
</body>
</html>
首先我們設置了兩個區塊,分別為:
然後,我們要從app內的數字與運算鍵的部分下手:
這裡的設計,我個人參考我的筆電鍵盤,排版的部分便是由num lock那邊往後數。
所以HTML的button元件們排序如下:
設計前,我們要先進行初始化,那我們一樣引入 Jack Sharkey 所撰寫的CSS初始化包:
<link rel="stylesheet" href="init.css">
初始化完畢後,目前我們的計算機長這樣:
接著,我們要使用 display:grid
做排版:
.app {
/* 設定初始化高度 */
min-height: 100vh;
/* grid排版 */
display: grid;
/* grid排版置中*/
justify-content: center;
align-content: center;
}
使用完grid
後,要設定他的行數跟排數:
.app {
min-height: 100vh;
display: grid;
justify-content: center;
align-content: center;
/* 設定行數跟排數 */
grid-template-columns: repeat(4,100px);
grid-template-rows: minmax(100px auto) repeat(5,100px);
}
當數字 & 運算鍵排版完畢後,我接著要編輯panel介面。
要使panel那列滿版:
.panel {
grid-column: 1/-1;
}
grid-column: 1/-1;
表示元素橫跨自第一列到最後一列。對panel上加一點設計樣式,使其變得更美觀:
.panel {
background-color: rgb(43, 25, 1);
}
.output {
color: white;
font-weight: bold;
font-size: xx-large;
}
.history {
min-height: 30px;
color: rgb(161, 161, 161);
}
.app>button {
padding: 30%;
background-color: wheat;
font-weight: bold;
}
再來我們要讓 +號按鈕
跟 =按鈕
佔滿兩格可以這樣寫 ── 先對要佔滿兩格的元素下一個class:
.col-2 {
grid-row: span 2;
}
計算機的樣式快完成了,接著我們讓panel介面的數字靠右對齊,並且使app介面內的按鍵在鼠標觸碰到按鍵時出現顏色變淺的樣式:
.panel {
background-color: rgb(43, 25, 1);
padding: 2% 1%;
text-align: right;
}
.app>button:hover {
background-color:rgba(245, 222, 179, 0.746);
}
這樣計算機的整體設計就完成了!
前面兩個文本終於撰寫完畢後,我們要撰寫JS的部分:
先創建一個 script.js
檔案並引入,或著使用 <script>
標籤將其腳本直接寫在HTML的元件裡。
我們接著來宣告一個calculator的物件:
class Calculator {
panel = $(".panel");
history = $(".history");
output = $(".output");
constructor () {
}
numberClick () { }
add() {}
minus () { }
times () { }
division () { }
equal () { }
delete() { }
clear() { }
}
calculator = new Calculator()
接著要先建立用來存放數值的變數:
data = "";
prev_data = "";
當我們點擊數字鍵時,我們會把number加到data上,並顯示出來。
所以我們要做一個 update()
,目的是把data顯示出來。
update() {
this.output.html(this.data);
}
numberClick()
:把資料傳進去data裡,並顯示出來。
numberClick (number) {
this.data += number;
this.update();
}
咦?為甚麼可以點兩次小數點?
為了不要出現兩個小數點或第一位為小數點的狀況出現,所以我們必須做防呆:
0
時直接替代數字。當條件成立時,這裡使用return直接跳出function。
numberClick(number) {
if (this.data === "" && number === "." ) { return }
if (this.data.includes(".") && number === ".") { return }
if (this.data[0] === "0") {
this.data = number;
this.update();
return
}
this.data += number;
this.update();
}
clear()
:套在AC按鍵上,目的是為了把把現有的data跟prevData清空。clear() {
this.data = "0";
this.prev_data = "";
this.update();
}
delete()
:套用在delete按鍵上,能使 data
倒退一格。delete() {
if (this.data.length > 1) {
this.data = this.data.slice(0, -1);
} else {
this.data = "0";
}
this.update();
}
update
函式update() {
this.output.html(this.data);
this.history.html(this.prev_data + " " + this.operator);
}
setOperator()
的作用是把 data
資料打進去 prev_data
哩,並把資料清空。
這裡的防呆是,當上面有資料時,就不用推資料上去,直接更改運算子就可以了。
setOperator(operator) {
if (this.prev_data.length === 0) {
this.prev_data = this.data;
this.data = "0";
}
this.operator = operator;
this.update();
}
add() {
this.setOperator("+");
}
minus() {
this.setOperator("-");
}
times() {
this.setOperator("*");
}
division() {
this.setOperator("/");
}
equal()
函式根據現在的operator去做對應的運算:
運算的部分是把 this.data
跟 this.prev_data
的字串分別轉成數字,運算後推回字串,再更新於panel上。
equal() {
switch (this.operator) {
case "+":
console.log("+");
this.data = parseFloat(this.prev_data) + parseFloat(this.data);
break;
case "-":
console.log("-");
this.data = parseFloat(this.prev_data) - parseFloat(this.data);
break;
case "*":
console.log("*");
this.data = parseFloat(this.prev_data) * parseFloat(this.data);
break;
case "/":
console.log("/");
this.data = parseFloat(this.prev_data) / parseFloat(this.data);
break;
}
this.data = this.data.toString();
this.prev_data = "";
this.operator = "";
this.update();
}
clear()
函式clear() {
this.data = "0";
this.prev_data = "";
this.update();
}
完整的JS代碼如下:
class Calculator {
panel = $(".panel");
history = $(".history");
output = $(".output");
data = "0";
prev_data = "";
operator = "";
constructor() {
this.update()
}
numberClick(number) {
if (this.data === "" && number === "." ) { return }
if (this.data.includes(".") && number === ".") { return }
if (this.data[0] === "0") {
this.data = number;
this.update();
return
}
this.data += number;
this.update();
}
setOperator(operator) {
if (this.prev_data.length === 0) {
this.prev_data = this.data;
this.data = "0";
}
this.operator = operator;
this.update();
}
add() {
this.setOperator("+");
}
minus() {
this.setOperator("-");
}
times() {
this.setOperator("*");
}
division() {
this.setOperator("/");
}
equal() {
switch (this.operator) {
case "+":
console.log("+");
this.data = parseFloat(this.prev_data) + parseFloat(this.data);
break;
case "-":
console.log("-");
this.data = parseFloat(this.prev_data) - parseFloat(this.data);
break;
case "*":
console.log("*");
this.data = parseFloat(this.prev_data) * parseFloat(this.data);
break;
case "/":
console.log("/");
this.data = parseFloat(this.prev_data) / parseFloat(this.data);
break;
}
this.data = this.data.toString();
this.prev_data = "";
this.operator = "";
this.update();
}
delete() {
if (this.data.length > 1) {
this.data = this.data.slice(0, -1);
} else {
this.data = "0";
}
this.update();
}
clear() {
this.data = "0";
this.operator = "";
this.prev_data = "";
this.update();
}
update() {
this.output.html(this.data);
this.history.html(this.prev_data + " " + this.operator);
}
}
calculator = new Calculator()
這樣,我們的計算機就大功告成啦!
本篇完成的網站在這裡!
https://ttdragon0722.github.io/A-Calculator/
Source Code:
https://github.com/ttdragon0722/A-Calculator
希望本日有關計算機製作的篇章,不會令您覺得太燒腦,靜下心來、慢慢研究 ── 期待有一日您也能靈活運用程式語言,創作出樣式更不同,或更複雜的計算機!明日的篇章我們將講解GitHub等相關內容,明天見!