JS => 계산기 만들기

CHO_velog·2021년 6월 24일
4

HTML 코드

같은 행의 버튼 라인 별로 태그박스를 감싸주도록 했다.

위 계산기 HTML 코드

    <div class="container">
      <div class="calculator">
        <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>
    </div>

css 코드

위 계산기 CSS 코드

.container {
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
.calculator {
  background-color: #06597a;
  width: 350px;
  height: 500px;
  border-radius: 10px;
  padding: 10px 20px;
  border: solid 6px #ffffff;
}
.calculator__display--for-advanced {
  background-color: #f09393;
  height: 100px;
  width: 100%;
  border-radius: 10px;
  font-size: 30px;
  text-align: center;
  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;
  font-size: 25px;
}
.clear__and__enter {
  text-align: center;
  height: 50px;
  margin: 10px;
  border-radius: 10px;
  background-color: #ffffff;
}
.clear__and__enter > button {
  border-radius: 10px;
  width: 125px;
  height: 50px;
  margin: 0px 0px;
  background-color: #f09393; 
  cursor: pointer;
  outline: none;
  border: 0px solid #30bb98;
}
.button__row {
  border-radius: 10px;
  text-align: center;
  height: 50px;
  margin: 10px;
  background-color: #ffffff;
}
.button__row > button {
  width: 60px;
  height: 50px;
  border-radius: 10px;
  cursor: pointer;
  outline: none;
  background-color: #bdb2b2;
}
.button__row > .operator {
  color: #ffffff;
  background-color: #313132;
}
.button__row > .double {
  width: 125px;
}
.button__row > .isPressed {
  background-color: #00da75;
}

JavaScript 코드

자바스크립트로 계산기 기능 구현하기

'document.querySelector'를 이용하여 기능을 구현하고자 하는 html의 엘리먼트들을 가져옴.

const calculator = document.querySelector('.calculator'); // calculator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있음.
const buttons = calculator.querySelector('.calculator__buttons'); // calculator__keys 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있음.
const operator = document.querySelector('.calculator__operator'); // calculator__operator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있음.
const display = document.querySelector('.calculator__display--for-advanced'); // calculator__display 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있음.

계산기가 계산을 할 수 있도록 계산 함수 작성.

function calculate(n1, operator, n2) {
  let result = 0;
  if(operator === '+') {
    result = Number(n1) + Number(n2); // '+'버튼을 눌렀을 때
  }
  else if(operator === '-') {
     result = Number(n1) - Number(n2); // '-'버튼을 눌렀을 때
  }
  else if(operator === '*') {
     result = Number(n1) * Number(n2); // '*'버튼을 눌렀을 때
  }
  if(operator === '/') {
     result = Number(n1) / Number(n2); // '/'버튼을 눌렀을 때
  }
  return String(result);
}

상황별 기능을 구현하기 위한 변수 설정.

let firstNum = '';
let operatorForAdvanced = '';
let previousKey = '';
let previousNum = '';

계산기 버튼을 눌렀을 때 작동하는 함수 구현

buttons.addEventListener('click', function (event) {
  const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장되어 있음.
  const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져옴.
  const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져옴.
<br>
  if (target.matches('button')) {
    if (action === 'number') { //클릭된 HTML 엘리먼트의 클래스 네임이 'number'라면
      if (display.textContent === '0' && operatorForAdvanced === '') {
        display.textContent = buttonContent;
        firstNum = display.textContent // 첫번째 숫자를 변수에 할당
      } // 기존 계산기 숫자가 0이고, 오퍼레이터 버튼이 안눌린 상태의 분기
      else if (display.textContent !== '0' && operatorForAdvanced === ''){
        display.textContent = display.textContent + buttonContent;
       // textContent는 문자열이기 때문에 기존 계산기에서 보여지는 숫자에 +연산자로 구현 
        firstNum = display.textContent ;
      } // 기존 계산기 숫자가 0이 아니고, 오퍼레이터 버튼이 안눌린 상태의 분기
        // ex) 15를 누르기 위해 1을 누른 상태의 분기(두자리 연속 누르기 위한 코드)
      else if (display.textContent !== '0' && operatorForAdvanced !== '') {
        if(previousKey === operatorForAdvanced) {
          display.textContent = buttonContent;
          previousKey = display.textContent; 
          // 직전키를 변수에 할당 (직전키가 오퍼레이터냐 숫자냐에 따라 계산기의 다양한 기능을 구현하기 위함)
          previousNum = display.textContent; // 직전 숫자를 변수에 할당
        } // 기존 계산기 숫자가 0이 아니고, 오퍼레이터 버튼이 눌린 상태의 분기
          // ex) 15+7을 하기 위해 15와 +를 누른 상태(두번째 숫자를 누르기 위한 코드)
        else if(previousKey !== operatorForAdvanced) {
          display.textContent = display.textContent + buttonContent;
          previousNum = display.textContent;
        } // ex) 15+17을 하기 위해 15와 +, 1을 누른 상태(17을 완성하기 위한 코드)
      }    
    }
<br>
    if (action === 'operator') { // //클릭된 HTML 엘리먼트의 클래스 네임이 'operator'일때 분기
      operatorForAdvanced = buttonContent; // 오퍼레이터 누를 때 누른 텍스트 정보 할당
      previousKey = operatorForAdvanced; // 직전키에 오퍼레이터 텍스트 정보 할당
    }
<br>
    if (action === 'clear') { // AC(초기화) 버튼을 누를 때 분기
      display.textContent = '0';
      firstNum = '';
      previousNum = '';
      operatorForAdvanced = '';
      previousKey = '';
    }
<br>
    if (action === 'calculate') { // Enter(계산) 버튼을 누를 때
      if(firstNum !== '' && operatorForAdvanced === '') {
        display.textContent = firstNum;
      }
      else if(firstNum !== '' && previousNum === '') {
        display.textContent = calculate(display.textContent, operatorForAdvanced, display.textContent)
      } // 기존에 작성했던 calculate 함수를 이용하여 계산 상황에 따른 전달인자와 함께 호출
      else if(previousKey === display.textContent){
        display.textContent = calculate(firstNum, operatorForAdvanced, previousNum)
        //   if(operatorForAdvanced === '+') {
        //   display.textContent = String(Number(firstNum) + Number(previousNum));
        // } else if(operatorForAdvanced === '-') {
        //   display.textContent = String(Number(firstNum) - Number(previousNum));
        // } else if(operatorForAdvanced === '*') {
        //   display.textContent = String(Number(firstNum) * Number(previousNum));
        // } else if(operatorForAdvanced === '/') {
        //   display.textContent = String(Number(firstNum) / Number(previousNum));      
        // } // 기존에 작성했던 하드코딩..!       
       } 
       else if(previousKey !== display.textContent && previousNum !== '') {
        display.textContent = calculate(display.textContent, operatorForAdvanced, previousNum)
       }   
       else if(previousKey !== display.textContent && previousNum === '') {
        display.textContent = firstNum;
       }
     }
   }
});

내가 HTML을 이용하여 자바스크립트로 기능을 구현할 때, 중요한 느낀점은..!
1. HTML 엘리먼트들을 가져오고, 사용하기 위해 class 네임을 기능과 유사한 단어로 구성해야 한다!
2. 컴퓨터는 내가 짠 코드의 순서에 따라 작동하기 때문에 분기를 잘 해야한다!
3. 변수를 활용하여 기능 구현의 다양한 상황에 맞게 꺼내 쓸 수 있다는 점!

profile
개발신생아

0개의 댓글