iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0

前些日子呢,我們一同學習了許多有關網頁三件套 —— HTML、CSS、JS的內容。納在本日的篇章中,我將帶著您使用這幾日所學,來實作出一個計算機的應用!

完成效果:https://ttdragon0722.github.io/A-Calculator/

範例如下圖所示:
https://ithelp.ithome.com.tw/upload/images/20230930/20160488PzoZxRJtoG.png

HTML - 從入門到放棄、精通啦。


<!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>

首先我們設置了兩個區塊,分別為:

  1. app主體,用以存放所有數字 & 運算鍵。
  2. pannel區塊,用以存放history(歷史數值) & input(當前輸入數值)。

然後,我們要從app內的數字與運算鍵的部分下手:
https://ithelp.ithome.com.tw/upload/images/20230930/20160488V4KxXiowbW.jpg

這裡的設計,我個人參考我的筆電鍵盤,排版的部分便是由num lock那邊往後數。
https://ithelp.ithome.com.tw/upload/images/20230930/20160488uRsxZXLyJZ.jpg

所以HTML的button元件們排序如下:
https://ithelp.ithome.com.tw/upload/images/20230930/20160488trNhFkBs60.png

CSS - 全場最靚的計算機!


設計前,我們要先進行初始化,那我們一樣引入 Jack Sharkey 所撰寫的CSS初始化包:

<link rel="stylesheet" href="init.css">

初始化完畢後,目前我們的計算機長這樣:
https://ithelp.ithome.com.tw/upload/images/20230930/20160488zgZ0WY2zNu.png

接著,我們要使用 display:grid 做排版:

.app {
		/* 設定初始化高度 */
    min-height: 100vh;
		/* grid排版 */
    display: grid;
		/* grid排版置中*/
    justify-content: center;
    align-content: center;
}

https://ithelp.ithome.com.tw/upload/images/20230930/20160488Q5TD4oVmAU.png

使用完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);
}

https://ithelp.ithome.com.tw/upload/images/20230930/20160488dMWp3ALOgk.png

當數字 & 運算鍵排版完畢後,我接著要編輯panel介面。
要使panel那列滿版:

.panel {
    grid-column: 1/-1;
}
  • grid-column: 1/-1; 表示元素橫跨自第一列到最後一列。
    https://ithelp.ithome.com.tw/upload/images/20230930/20160488R90ItjK4E9.png

對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;
}

https://ithelp.ithome.com.tw/upload/images/20230930/2016048856qDvwy90N.png

再來我們要讓 +號按鈕=按鈕 佔滿兩格可以這樣寫 ── 先對要佔滿兩格的元素下一個class:
https://ithelp.ithome.com.tw/upload/images/20230930/20160488X6P7BSOwRJ.png

.col-2 {
    grid-row: span 2;
}

https://ithelp.ithome.com.tw/upload/images/20230930/20160488eGtOyOBAYs.png

計算機的樣式快完成了,接著我們讓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);
}

https://ithelp.ithome.com.tw/upload/images/20230930/20160488zsazKBiEfd.png

這樣計算機的整體設計就完成了!

JS - 你也渴望計算嗎?


前面兩個文本終於撰寫完畢後,我們要撰寫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()

https://ithelp.ithome.com.tw/upload/images/20230930/20160488G4EEcBmMh9.png
https://ithelp.ithome.com.tw/upload/images/20230930/20160488iGkwIY85W3.png

接著要先建立用來存放數值的變數:

data = "";
prev_data = "";

當我們點擊數字鍵時,我們會把number加到data上,並顯示出來。
所以我們要做一個 update() ,目的是把data顯示出來。

update() {
    this.output.html(this.data);
}

numberClick() :把資料傳進去data裡,並顯示出來。

numberClick (number) {
    this.data += number;
    this.update();
}

https://ithelp.ithome.com.tw/upload/images/20230930/20160488MCBUz7JjcZ.png

咦?為甚麼可以點兩次小數點?

為了不要出現兩個小數點或第一位為小數點的狀況出現,所以我們必須做防呆:

  • 當輸出結果為空,不加新的數字。
  • 當輸出裡有小數點,不加新的數字。
  • 當第一個輸出的第一個字為 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.datathis.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() 函式
    這裡多了一個operator,所以這裡要小小的更動:
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://ithelp.ithome.com.tw/upload/images/20230930/20160488IATw1ToJQp.png

本篇完成的網站在這裡!
https://ttdragon0722.github.io/A-Calculator/

Source Code:
https://github.com/ttdragon0722/A-Calculator


希望本日有關計算機製作的篇章,不會令您覺得太燒腦,靜下心來、慢慢研究 ── 期待有一日您也能靈活運用程式語言,創作出樣式更不同,或更複雜的計算機!明日的篇章我們將講解GitHub等相關內容,明天見!


上一篇
【Day14】Javascript物件設計!我所知道的物件導向。
下一篇
【Day16】Github介紹:讓大家看到你的網頁!
系列文
連我阿公都會-手把手教你架網站 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言