[實作] 匯率轉換器

學習到的知識點

HTML

  • select裡的option選項,加上selected可以讓選項固定。

CSS

  • background: transparent是黑色且全透明,用於元素重疊又想顯示被重疊的元素。

  • media query

JS

  • fetch
  • promise
  • Synchronous與Asynchronous
  • toFixed(N) 取小數第N位

簡介

HTML

結構

select 包住 option,加上selected可以讓下拉式選單停留在特定選項。

input 加上type=numberid,還有value

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<img src="img/money.png" alt="" class="money-img" />
<h1>Exchange Rate Calculator</h1>
<p>Choose the currency and the amounts to get the exchange rate</p>

<div class="container">
<div class="currency">
<select id="currency-one">
<option value="GBP">GBP</option>
<option value="TWD" selected>TWD</option>
<option value="UAH">UAH</option>
</select>
<input type="number" id="amount-one" placeholder="0" value="1" />
</div>

第二部分的select一樣做法。

swap按鈕與匯率

設定id才可以使用getElementById取得元素。

1
2
3
4
<div class="swap-rate-container">
<button class="btn" id="swap">Swap</button>
<div class="rate" id="rate"></div>
</div>

CSS

顏色變數

1
2
3
4
/* color variable */
:root {
--primary-color: #5fbaa7;
}

將元素定位到中間

許多教學會在一開始就設定box-sizing: border-box;,原因是因為盒模型本身是需要去計算padding,margin,還有border的粗細。但是,加上了box-sizing: border-box;之後,就不需要去計算盒模型,他也會維持在我們一開始設定的寬度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
* {
box-sizing: border-box;
}

body {
background-color: #f4f4f4f4;
font-family: Arial, Helvetica, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
padding: 20px;
}

一些基本設定

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
h1 {
color: var(--primary-color);
}

p {
text-align: center;
}

.btn {
color: #fff;
background: var(--primary-color);
cursor: pointer;
border-radius: 5px;
font-size: 12px;
padding: 5px 12px;
}

.money-img {
width: 150px;
}

.currency {
padding: 40px 0;
display: flex;
align-items: center;
justify-content: space-between;
}

設定貨幣選項外觀與輸入

background: transparent是==黑色且全透明==rgba(0,0,0,0),如果一個元素需要將他覆蓋在另外一個元素上,而我們又需要==顯示下面的元素==,就會使用到此屬性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.currency select {
padding: 10px 30px 10px 10px;
/* 取消selected預設樣式 */
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
border: 1px solid #dedede;
font-size: 16px;
/* rgba(0,0,0,0) */
background: transparent;
/* 向下的三角形的ㄊㄨ˙ */
background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22292.4%22%20height%3D%22292.4%22%3E%3Cpath%20fill%3D%22%20000002%22%20d%3D%22M287%2069.4a17.6%2017.6%200%200%200-13-5.4H18.4c-5%200-9.3%201.8-12.9%205.4A17.6%2017.6%200%200%200%200%2082.2c0%205%201.8%209.3%205.4%2012.9l128%20127.9c3.6%203.6%207.8%205.4%2012.8%205.4s9.2-1.8%2012.8-5.4L287%2095c3.5-3.5%205.4-7.8%205.4-12.8%200-5-1.9-9.2-5.5-12.8z%22%2F%3E%3C%2Fsvg%3E");
background-position: right 10px top 50%, 0, 0;
background-size: 12px auto, 100%;
background-repeat: no-repeat;
}

/* 輸入選項 */
.currency input {
border: 0;
background: transparent;
font-size: 30px;
text-align: right;
}

匯率的顯示外觀

outline: 0,取消點下去後,出現的線條外框樣式。

@media (max-width: 600px),當螢幕寬度小於600時,改變輸入框與h1的大小。

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
.swap-rate-container {
display: flex;
align-items: center;
justify-content: space-between;
}

.rate {
color: var(--primary-color);
font-size: 14px;
padding: 0 10px;
}

select:focus,
input:focus,
button:focus {
outline: 0;
}

@media (max-width: 600px) {
.currency input {
width: 200px;
}
h1 {
text-align: center;
}
}

JS

設定變數讀取表單變化

addEventListener和電影選位的下拉式選單讀取方法一樣,都是使用change

  • input 事件: 當 input、 textarea 以及帶有 contenteditable 的元素內容被改變時,就會觸發 input 事件。
  • change 事件: 當 input、select、textarea、radio、checkbox 等表單元素被改變時觸發。 但與 input 事件不同的是,==input 事件會在輸入框輸入內容的當下觸發==,而 ==change 事件則是在目前焦點離開輸入框後==才觸發。
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
// 選擇要轉換的匯率1(ex TWD)
const currencyEl_one = document.getElementById("currency-one");
// 匯率的總計1
const amountEl_one = document.getElementById("amount-one");
// 選擇要轉換的匯率2(ex USD)
const currencyEl_two = document.getElementById("currency-two");
// 匯率的總計2
const amountEl_two = document.getElementById("amount-two");
// 顯示匯率的文字
const rateEl = document.getElementById("rate");

//swap button
const swap = document.getElementById("swap");

//Fetch exchage rates and update the DOM
// 取得匯率更新使用(fetch) 以及 把取得的資料更新DOM
function caclulate() {
console.log("RUN");
}

// Event Listeners
//下拉選單的變化是使用change
currencyEl_one.addEventListener("change", caclulate);
// 輸入框是使用input
amountEl_one.addEventListener("input", caclulate);
currencyEl_two.addEventListener("change", caclulate);
amountEl_two.addEventListener("input", caclulate);

// 呼叫函式
caclulate();

使用Fetch方法取得匯率資料

Fetch和Promise是什麼?

網址的最後為貨幣的種類,所以在最後設變數,就可以即時取得不同種類的貨幣資料。
https://api.exchangerate-api.com/v4/latest/TWD

會取到的json資料,透過線上轉換變成較容易觀看的格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
function caclulate() {
// ex.TWD
const currency_one = currencyEl_one.value;
const currency_two = currencyEl_two.value;
// 使用網址更改最後的部分就可以取得更新選擇的資料
fetch(`https://api.exchangerate-api.com/v4/latest/${currency_one}`)
// 取得的檔案為 json 格式,所以在 fetch 取得檔案之後
// 透過json()的方法處理檔案
.then((res) => res.json())
.then((data) => {
console.log(data);
});
}

顯示出選擇的貨幣匯率 & 計算轉換後的價格

使用ES6語法‵‵,裡面使用$將變數放進去。

toFixed(N)為取小數第N位。

1
2
3
4
5
6
7
8
9
  fetch(`https://api.exchangerate-api.com/v4/latest/${currency_one}`)
.then((res) => res.json())
.then((data) => {
console.log(data);
const rate = data.rates[currency_two];
rateEl.innerHTML = `1 ${currency_one} = ${rate} ${currency_two}`;
amountEl_two.value = (amountEl_one.value * rate).toFixed(2);
});
}

點選swap按鈕可以上下顛倒貨幣

使用temp變數幫助進行調換。

1
2
3
4
5
6
7
8
9
10
swap.addEventListener("click", () => {
//先將one放到temp裡
const temp = currencyEl_one.value;
//再將two丟到one裡
currencyEl_one.value = currencyEl_two.value;
//原先在temp裡面的one放到two裡面,完成交換。
currencyEl_two.value = temp;
caclulate();
});

參考文章

css中的transparent是什么意思有什么作用?

重新認識 JavaScript: Day 16 那些你知道與不知道的事件們


[實作] 匯率轉換器
https://phoebeho.com/Portfolio/20210120/3462246270/
作者
Phoebe
發布於
2021年1月20日
許可協議