Javascript 계산기 구현

왕지호·2022년 11월 1일
0
  • Bare Minimum, Advanced, Nightmare 포함! 내가 만든 계산기에 적용시키기!
  • 주석 참고

  • 동영상은 어떻게 첨부하는걸까...
  • 그 대신 노션에 구현 동영상 올려둔거 첨부합니다! 혹시라도 보시는 분 계시면 참고하시기 바랍니다!
    구현 동영상
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(n1, operator, n2) {
  let result = 0;
  // TODO : n1과 n2를 operator에 따라 계산하는 함수를 만드세요.
  // ex) 입력값이 n1 : '1', operator : '+', n2 : '2' 인 경우, 3이 리턴됩니다.
  if (operator === "+") result = parseFloat(n1) + parseFloat(n2);
  else if (operator === "-") result = parseFloat(n1) - parseFloat(n2);
  else if (operator === "*") result = parseFloat(n1) * parseFloat(n2);
  else if (operator === "/") result = parseFloat(n1) / parseFloat(n2);
  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이면
      // 아래 코드가 작동됩니다.

      if (firstOperend.textContent === "0") {
        //왼쪽 숫자가 0이라면 누른 숫자가 왼쪽에 입력
        firstOperend.textContent = buttonContent;
      } else {
        //아니면 오른쪽에 입력
        secondOperend.textContent = buttonContent;
      }
      console.log("숫자 " + buttonContent + " 버튼");
    }

    if (action === "operator") {
      console.log("연산자 " + buttonContent + " 버튼");
      //연산자를 누르면 적용
      operator.textContent = buttonContent;
    }

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

    if (action === "clear") {
      console.log("초기화 버튼");
      //왼쪽, 오른쪽, 연산자 초기(+)로 설정, 결과 0으로 초기화
      firstOperend.textContent = "0";
      secondOperend.textContent = "0";
      operator.textContent = "+";
      calculatedResult.textContent = "0";
    }

    if (action === "calculate") {
      //왼쪽 입력숫자, 연산자, 오른쪽 입력숫자 순으로 계산
      calculatedResult.textContent = calculate(
        firstOperend.textContent,
        operator.textContent,
        secondOperend.textContent
      );
      console.log("계산 버튼");
    }
  }
});

// ! 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") {
      if (display.textContent === "0" || previousKey === "operator") {
        //화면 숫자가 0 (초기화면 0에서 숫자 입력) or 숫자 누른 뒤 연산자 누른 경우
        //지금 화면에 새로 입력한 숫자 띄우기
        display.textContent = buttonContent;
      } else {
        //화면 숫자가 0이 아닌 경우 뒤에 숫자 추가
        //기존 값(string)뒤에 새로 입력한 숫자 추가
        display.textContent += buttonContent;
      }
      previousKey = "number";
    }
    if (action === "operator") {
      //연산자 누르고 입력한 숫자(지금 화면에 떠있는거) 변수에 할당

      //nightmare 마지막 테스트 케이스
      //opeator를 처음 눌렀을 때는 계산이 일어날 필요가 없다
      //operator가 있고, firstNum이 있다 -> 이전에 이미 operator을 누른 적이 있다.
      if (
        firstNum &&
        operatorForAdvanced &&
        previousKey !== "calculate" &&
        previousKey !== "operator"
      ) {
        display.textContent = calculate(
          firstNum,
          operatorForAdvanced,
          display.textContent
        );
      }

      firstNum = display.textContent;
      operatorForAdvanced = buttonContent;
      previousKey = "operator"; //방금전에 누른 키
    }
    if (action === "decimal") {
      //만약 지금 보여지고 있는 화면에 . 이 포함되어 있지 않으면, 그리고 방금 누른 키가 operator가 아니라면
      if (!display.textContent.includes(".") && previousKey !== "operator") {
        //그 뒤에 소숫점 추가 입력
        display.textContent += ".";
      } else if (previousKey === "operator") {
        //누른 버튼(값) 보여주기
        display.textContent = "0.";
      }
      previousKey = "decimal";
    }
    if (action === "clear") {
      //화면 숫자를 0, 연산자를 초기값인 undefined로
      firstNum = undefined;
      display.textContent = "0";
      operatorForAdvanced = undefined;
      previousKey = "clear";
    }
    if (action === "calculate") {
      //연산자가 있을 때
      if (operatorForAdvanced) {
        if (previousKey === "calculate") {
          display.textContent = calculate(
            display.textContent,
            operatorForAdvanced,
            previousNum
          );
          //계산하고 나온 결과 + 연산자 + 지금 화면에 보여진 결과
        } else {
          previousNum = display.textContent;
          display.textContent = calculate(
            firstNum,
            operatorForAdvanced,
            display.textContent
          );
        }
      }
      previousKey = "calculate";
    }
  }
});
profile
개발 공부하는 코린이!

0개의 댓글