DAY9

임경섭·2023년 3월 2일
0

오늘은 계산기 구현하기를 진행했다.
기능이 크게 없어서 간단하다고 생각했으나, 생각보다 로직을 짜기 어려웠다.

우선 계산기.html이다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript Calculator</title>
    <link href="https://fonts.googleapis.com/css?family=Righteous" rel="stylesheet">
    <link rel="stylesheet" href="./yourStyle.css">
</head>
<body>
    <div class="container">
      <div class="calculator">
        <div class="calculator__display--bare">
          <span class="calculator__operend--left">0</span>
          <span class="calculator__operator">+</span>
          <span class="calculator__operend--right">0</span>
          <span class="calculator__equal">=</span>
          <span class="calculator__result">0</span>
        </div>
        <div class="calculator__display--for-advanced">0</div>
        <div class="calculator__buttons">
          <div class="clear__and__enter">
            <button class="clear">AC</button>
            <button class="calculate">Enter</button>
          </div>
          <div class="button__row">
            <button class="number">7</button>
            <button class="number">8</button>
            <button class="number">9</button>
            <button class="operator">+</button>
          </div>
          <div class="button__row">
            <button class="number">4</button>
            <button class="number">5</button>
            <button class="number">6</button>
            <button class="operator">-</button>
          </div>
          <div class="button__row">
            <button class="number">1</button>
            <button class="number">2</button>
            <button class="number">3</button>
            <button class="operator">*</button>
          </div>
          <div class="button__row">
            <button class="number double">0</button>
            <button class="decimal">.</button>
            <button class="operator">/</button>
          </div>
        </div>
      </div>
      <img class="logo" src="data/codestates-logo.png">
    </div>
    <script src='./script.js'></script>
</body>
</html>

그리고 계산기.css이다.

/* TODO : CSS파일을 편집하여 원하는 스타일의 계산기를 만들어보세요 :) */

/* global */
* {
  margin: 0;
  padding: 0;
  border: 0px;
  box-sizing: border-box;
  font-family: "Righteous", cursive;
  color: #000;
}

body {
  background-image: url("./data/codestates-motif.png");
}

/*
  Calculator styles
*/

.container {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.calculator {
  background-color: #4000c7;
  width: 350px;
  height: 500px;
  border-radius: 10px;
  padding: 30px 20px;
}

.calculator__display--bare {
  display: none;
  background-color: #ffffff;
  text-align: center;
  vertical-align: middle;
  height: 100px;
  width: 100%;
  border-radius: 10px;
  font-size: 20px;
  padding: 25px 15px;
  overflow: hidden;
  overflow-wrap: break-word;
}

.calculator__display--bare > span {
  display: inline-block;
  text-align: center;
  background-color: #f3f0fc;
  margin: 5px;
  width: 40px;
  height: 45px;
  border-radius: 10px;
  font-size: 20px;
  padding: 10px 5px;
}

.calculator__display--for-advanced {
  /* 이 줄을 모두 지우면 advanced 테스트를 하실 수 있습니다.*/
  background-color: #ffffff;
  height: 100px;
  width: 100%;
  border-radius: 10px;
  font-size: 20px;
  text-align: right;
  vertical-align: middle;
  padding: 25px 15px;
  overflow: hidden;
  overflow-wrap: break-word;
}

.calculator__buttons {
  background-color: #ffffff;
  width: 100%;
  height: 330px;
  margin-top: 10px;
  padding: 10px;
  border-radius: 10px;
}

.clear__and__enter {
  height: 50px;
  margin: 10px;
  background-color: #f3f0fc;
}

.clear__and__enter > button {
  border-radius: 10px;
  width: 50px;
  height: 40px;
  margin: 0px 5px;
  background-color: #00da75;
  cursor: pointer;
  outline: none;
}

.button__row {
  height: 50px;
  margin: 10px;
  background-color: #f3f0fc;
}

.button__row > button {
  width: 50px;
  height: 40px;
  border-radius: 10px;
  cursor: pointer;
  outline: none;
  background-color: #ebebeb;
}

.button__row > .operator {
  color: #ffffff;
  background-color: #313132;
}

.button__row > .double {
  width: 115px;
}

.button__row > .isPressed {
  background-color: #00da75;
}

.logo {
  position: fixed;
  width: 204px;
  padding: 30px;
  bottom: 0px;
  right: 0px;
}

마지막으로 계산기.js이다.

const calculator = document.querySelector(".calculator"); // calculator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const buttons = calculator.querySelector(".calculator__buttons"); // calculator__keys 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.

const firstOperend = document.querySelector(".calculator__operend--left"); // calculator__operend--left 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const operator = document.querySelector(".calculator__operator"); // calculator__operator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const secondOperend = document.querySelector(".calculator__operend--right"); // calculator__operend--right 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const calculatedResult = document.querySelector(".calculator__result"); // calculator__result 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.

function calculate(a, operator, b) {
  console.log(a, operator, b);
  let result = 0;
  // TODO : n1과 n2를 operator에 따라 계산하는 함수를 만드세요.
  // ex) 입력값이 n1 : '1', operator : '+', n2 : '2' 인 경우, 3이 리턴됩니다.
  if (operator === "+") {
    result = Number(a) + Number(b);
  } else if (operator === "-") {
    result = Number(a) - Number(b);
  } else if (operator === "/") {
    result = Number(a) / Number(b);
  } else if (operator === "*") {
    result = Number(a) * Number(b);
  }
  console.log(result);
  return String(result);
}

buttons.addEventListener("click", function (event) {
  // 버튼을 눌렀을 때 작동하는 함수입니다.

  const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장되어 있습니다.
  const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져옵니다.
  const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져옵니다.
  // ! 위 코드(Line 19 - 21)는 수정하지 마세요.
  if (target.matches("button")) {
    // TODO : 계산기가 작동할 수 있도록 아래 코드를 수정하세요. 작성되어 있는 조건문과 console.log를 활용하시면 쉽게 문제를 풀 수 있습니다.
    // 클릭된 HTML 엘리먼트가 button이면
    if (action === "number") {
      // 그리고 버튼의 클레스가 number이면
      // 아래 코드가 작동됩니다.
      console.log("숫자 " + buttonContent + " 버튼");
      if (firstOperend.textContent === "0") {
        firstOperend.textContent = buttonContent;
      } else if (firstOperend.textContent !== 0) {
        secondOperend.textContent = buttonContent;
      }
    }

    if (action === "operator") {
      console.log("연산자 " + buttonContent + " 버튼");
      operator.textContent = buttonContent;
    }

    if (action === "decimal") {
      console.log("소수점 버튼");
    }

    if (action === "clear") {
      console.log("초기화 버튼");
      firstOperend.textContent = 0;
      secondOperend.textContent = 0;
      calculatedResult.textContent = 0;
    }

    if (action === "calculate") {
      console.log("계산 버튼");
      calculatedResult.textContent = calculate(
        firstOperend.textContent,
        operator.textContent,
        secondOperend.textContent
      );
    }
  }
});

// ! Advanced Challenge test와 Nightmare test를 위해서는 아래 주석을 해제하세요.

const display = document.querySelector(".calculator__display--for-advanced"); // calculator__display 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
let firstNum, operatorForAdvanced, previousKey, previousNum;

buttons.addEventListener("click", function (event) {
  // 버튼을 눌렀을 때 작동하는 함수입니다.

  const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장되어 있습니다.
  const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져옵니다.
  const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져옵니다.
  // ! 위 코드는 수정하지 마세요.

  // ! 여기서부터 Advanced Challenge & Nightmare 과제룰 풀어주세요.
  if (target.matches("button")) {
    if (action === "number") {
      //화면이 0이고 연산자가 없을때, 클릭 시 화면 출력
      if (display.textContent === "0" && operatorForAdvanced === undefined) {
        display.textContent = buttonContent;
        firstNum = display.textContent;
      } else if (
        display.textContent !== "0" &&
        operatorForAdvanced === undefined
      ) {
        display.textContent += buttonContent;
        firstNum = display.textContent;
      }
      //화면이 0이고 연산자가 있을때, 클릭시 새로운 값으로 화면 출력하고 previousNum에 저장
      else if (previousKey === "operator" && display.textContent !== "0") {
        display.textContent = buttonContent;
        previousNum = display.textContent;
      } else {
        display.textContent += buttonContent;
        previousNum = display.textContent;
      }
      previousKey = "number";
    }
    if (action === "operator") {
      // previousNum이 존재할 때
      if (previousNum) {
        firstNum = calculate(firstNum, operatorForAdvanced, previousNum);
        operatorForAdvanced = buttonContent;
        display.textContent = firstNum;
        previousNum = undefined;
      }
      // firstNum이 0이 아니고, previousKey가 number
      else if (firstNum !== "0" || previousKey === "number")
        operatorForAdvanced = buttonContent;
      previousKey = "operator";
    }
    if (action === "decimal") {
      if (!display.textContent.includes(".") && previousKey !== "operator") {
        display.textContent = display.textContent + ".";
      } else if (previousKey === "operator") {
        display.textContent = "0.";
        previousNum = "0.";
      }
      previousKey = "decimal";
    }
    if (action === "clear") {
      firstNum = undefined;
      previousNum = undefined;
      display.textContent = 0;
      operatorForAdvanced = undefined;
      previousKey = "clear";
    }
    if (action === "calculate") {
      if (previousNum === undefined)
        display.textContent = calculate(
          display.textContent,
          operatorForAdvanced,
          display.textContent
        );
      else if (previousKey === "calculate")
        display.textContent = calculate(
          display.textContent,
          operatorForAdvanced,
          previousNum
        );
      else
        display.textContent = calculate(
          firstNum,
          operatorForAdvanced,
          previousNum
        );
      previousKey = "calculate";
    }
  }
});

기본적으로 첫번째 숫자, 연산자, 두번째 숫자가 차례대로 입력되면 간단하게 구현할 수 있다. 하지만 첫번째 숫자와 연산자만 입력되는 경우나 계속 결과값(=)을 입력하는 경우 다르게 알고리즘을 짜야된다는게 어려워서 오래걸렸다.

profile
즐겁게 코딩 ૮₍ •̀ᴥ•́ ₎ა

0개의 댓글