iT邦幫忙

2022 iThome 鐵人賽

DAY 7
1
Modern Web

Have fun! 新手也能打造的Javascript微型專案系列 第 7

Have fun! 新手也能打造的Javascript微型專案! Day7: 老是算錢算不清,寫個簡單的計算機用用吧!(下)

  • 分享至 

  • xImage
  •  
tags: ItIron2022 Javascript

前言

今天我們將接續昨天的事前規劃,將剩餘的計算機功能完成,很多網站或應用程式只要一開始做好規劃,後續的事情都相對容易很多! 那我們馬上就開始吧!

Getting started

Step1: 實作數字按鈕功能

要做任何運算都少不了數字,所以首先我們先從這邊開始! 我們希望的目標很簡單,當點擊任何數字按鈕時,它便會一個一個出現在顯示匡中! 為了做到這點,先回顧一下我們在html的設計吧!

html structure

我們所有的數字按鈕都有"number"這個class name,同時該元素的textContent就是對應的數字(雖然是字串的形式表示),而數字顯示的部分是由display這個input元素所決定的,知道這幾點後我們就可以開始處理這部分的邏輯囉!

如果今天點擊的按鈕有包含number這個class,大致上我們需要做到以下的部分

  • 將數字以字串的方式與現有的值連接在一起並顯示在input欄位內,因此需要修改display.value的值
  • 若目前的值已經為0,則點擊數字按鈕不該直接連接起來(注意,這裡不管是displayBar.value或是e.target.textContent都是字串,並不會變成數字相加),不然會出現000123這樣奇怪的數字,我們需要直接取代現有的值(比方說現在的值為0,點擊6按鈕後應該直接讓值為6)

請你在script.js中補上handleBtnClick函數的內容


const displayBar = document.querySelector(".display");
const calculator = document.querySelector(".calculator");

const operatorMapping = {
  "+": (a, b) => a + b,
  "-": (a, b) => a - b,
  "x": (a, b) => a * b,
  "/": (a, b) => a / b,
};

let operatorClicked = false;
let previousResult = "";
let operator;

function handleBtnClick(e) {
  // 處理所有數字
  if (e.target.classList.contains("number")) {
    if (displayBar.value === "0") {
        displayBar.value = e.target.textContent;
      return;
    }
    displayBar.value += e.target.textContent;
  }
}

calculator.addEventListener("click", handleBtnClick);

暫時這樣沒有問題了,數字可以正確地顯示在input欄位中! well done!

Step2: 實作運算符按鈕功能

運算符的處理聽起來很困難,實際上的程式碼會遠比你想像的簡單,我們要做的只是

  1. 紀錄按運算符之前的數字
  2. 紀錄運算符(利用我們之前建立的operatorMapping物件)
  3. 將operatorClicked變數設為true

不過看到第3步,你可能有想到了我們之前的處理數字的部分需要修改! 當我們點擊運算符後,再次點擊數字時應該要先清空目前的結果,且將operatorClicked變數設為false,這麼一來我們才可以繼續輸入數字而不受之前的結果影響,請你照以下程式碼,修改handleBtnClick的部分並新增運算符的處理


// 以上省略

function handleBtnClick(e) {
  // 處理所有數字
  if (e.target.classList.contains("number")) {
    // 加入點擊運算符後的處理
    if (operatorClicked) {
      displayBar.value = "";
      operatorClicked = false;
    }  
    if (displayBar.value === "0") {
        displayBar.value = e.target.textContent;
      return;
    }
    displayBar.value += e.target.textContent;
  }
    
  // 處理運算符
  if (e.target.classList.contains("operator")) {
    operator = operatorMapping[e.target.textContent];
    previousResult = displayBar.value;
    operatorClicked = true;
  }  
}

calculator.addEventListener("click", handleBtnClick);

Step3: 實作"等於"按鈕功能

最後一步就是實際做運算囉! 我們目前已經湊齊

  • 之前的數字
  • 運算符
  • 現在的數字

那麼要做結果運算就相當簡單了,我們運算符變數紀錄的是一個函數,比方說當我點擊+按鈕時,operator便是(a, b) => a + b函數,因此我們可以輕鬆算出結果!

請在script.js中的監聽器函數補上以下的程式碼,唯一需要注意的是在傳入函數前需要先將值轉為數字,記得我們之前有提到過我們紀錄的值都是以字串形式,運算前需要做一次轉型。
同時在運算後需要將一切其他變數都復原,包含之前的變數、紀錄運算符是否被點擊的變數以及運算符紀錄的函數等,讓一切重新開始!

  // 處理等號
  if (e.target.classList.contains("equal")) {
    displayBar.value = operator(
      Number(previousResult),
      Number(displayBar.value)
    );
    previousResult = "";
    operatorClicked = false;
    operator = null;
  }

簡單測試一下我們目前的成果,非常好,一切如同我們想像的運作!

end demo

Step4: 換你動手囉

基本功能到此就全部結束了,但其實在ui上還有幾個按鈕是沒有功能的,不過在這樣的基礎結構設置完後,剩下的功能其實也會相當的簡單! 行有餘力的話歡迎自己試著完成剩餘的部分,對初學的你會是相當不錯的練習,祝你好運囉!

總結

今天我們完成了基本的計算機功能,你會發現這樣我們常用的東西在背後的邏輯其實並沒有這麼複雜,只要你先想清楚基本的結構,剩下的部分都只是幾行程式碼就可以搞定的東西囉!
明天我們會做另一個簡單的專案,敬請期待!

文章中的範例程式碼可以在這邊取得,歡迎自行取用

轉職Q & A

Danny,履歷的部分我弄得差不多了,但開始看職缺之後我發現有很多職缺描述我都不符合,這樣我是不是不應該去投遞那些職缺啊?

這也是相當常見的問題,一般不管是104或是cakeresume上,工程師職缺的JD(job description)總是洋洋灑灑一大篇,什麼需要兩年以上的工作經驗、要熟悉一大堆工具、LOL的牌位要鑽石以上之類的。我必須說,如果所有JD上的條件都要符合的話,那我現在的工程師經歷會是0,not joking. 許多JD其實只是HR自己寫的東西,講難聽點就真的是參考用,當然你可以從JD中看出你目前可能缺乏什麼技術或工具的熟練度,但其實你只要符合部分的描述就可以試試看! 畢竟一旦你履歷準備好,投遞的成本其實相當的低,那麼為什麼要因為一個不怎麼準確的職缺描述就阻擋你找一份可能適合你的工作呢?

同樣的道理也適用於一些職缺的title,即便上面是寫說要senior的人選,但實際上senior之間的落差實在太大,人人都想要強大的senior不過事實上就是這很稀缺,因此許多團隊遇到這種情況會退而求其次選有潛力的junior作為替代,因此若是你非常喜愛的公司那麼就不要被這些東西勸退,勇敢的出擊吧!

本文章同步發布於個人部落格,有興趣的朋友也可以來逛逛~!


上一篇
Have fun! 新手也能打造的Javascript微型專案! Day6: 老是算錢算不清,寫個簡單的計算機用用吧!(上)
下一篇
Have fun! 新手也能打造的Javascript微型專案! Day8: 日幣歷史新低!寫個匯率轉換器讓你知道你手邊的錢能換多少日幣吧!(上)
系列文
Have fun! 新手也能打造的Javascript微型專案30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言