Jieunny의 블로그

Unit6. [실습] 계산기 구현하기 본문

CodeStates/Training

Unit6. [실습] 계산기 구현하기

Jieunny 2022. 12. 21. 08:57

➰ 주요 구현 기능

 

📣 Bare Minimum Test

✔️ 기본적인 기능 구현

 

📣 Advanced Challenge Test

✔️ 숫자 버튼 누르고 화면에 숫자 입력 구현

if (target.matches('button')) {
        if(display.textContent === '0'|| previousKey === 'operator'){    //아직 어떠한 버튼도 안누른 경우
            display.textContent = buttonContent;    //누른 숫자를 화면에 띄운다.
        }
        else{
            display.textContent = display.textContent + buttonContent;  //숫자 하나를 누르고 다음 숫자를 누를 경우 ex) 70
        }
        previousKey = 'number';
    }
• 첫 실행이거나 연산자 다음 두번째 피연산자를 입력하는 경우라면 화면의 텍스트를 클릭한 엘리먼트의 텍스트로 바꿔준다.
• 두자리 숫자를 누를 경우는 화면에 나와있는 텍스트에 클릭한 엘리먼트의 텍스트롤 더해서 화면에 나타내준다.

📌 element.textContent = '내용'
• 특정 엘리먼트의 텍스트를 추가한다.
• 특정 엘리먼트의 텍스트를 가져온다.

 

✔️ Enter 버튼으로 계산하고 AC 버튼으로 초기화 구현

if (action === 'clear') {
        firstNum = undefined;  //첫번째 값 초기화
        operatorForAdvanced = undefined;   //연산자 초기화
        display.textContent = '0';  //화면 '0'으로 초기화
        previousKey = 'clear';
        previousNum = undefined;
        if (clickedOperator){ //  isPressed 클래스를 가진 요소가 있다면
          clickedOperator.classList.remove('isPressed');  // 삭제하기
        }
    }
• AC 버튼을 누르면 모든 변수를 초기화해준다.
🚨  null로 초기화 할 경우 기대한 기능이 구현되지 않는다.

 

✔️ Calculate 함수 정수 연산 구현

function calculate(n1, operator, n2) {
  let result = 0;
      if(operator === '+'){
        result = parseInt(n1) + parseInt(n2);
      }
      //...
  }
• parseInt() 메소드를 사용한다.

 

 

📣 Nightmare Test

 

✔️ Calculate 함수 실수 연산 구현

function calculate(n1, operator, n2) {
  let result = 0;
      if(operator === '+'){
        result = parseFloat(n1) + parseFloat(n2);
      }
      //...
  }
• parseInt() -> parseFloat() 로 변경해서 실수 연산을 가능하게 한다.

 

✔️ 연산 후 Enter 여러 번 누르면 반복 연산 구현

✔️ 숫자 - Enter - 연산자 - 숫자 연산 구현

if (action === 'calculate') {
        if(operatorForAdvanced === undefined){  //(1) 연산자 안누르고 숫자 다음 계속 엔터 누를경우
            display.textContent = display.textContent;
        }
        else{
            if(previousKey !== 'calculate'){    //(2) 숫자 다음 엔터 처음 눌렀을 때
                previousNum = display.textContent;
                display.textContent = calculate(firstNum, operatorForAdvanced, display.textContent);
                console.log("previousNum: " ,previousNum);
                previousKey = 'calculate';
            }
            else if(previousKey === 'calculate'){   //(3) 게산 하고 계속 엔터 누를 때
                display.textContent = calculate(display.textContent, operatorForAdvanced, previousNum);
            }
        }
    }
• 연산 후 Enter를 계속 누르면 calculate함수로
(화면에 보이는 결과,  직전에 눌렀던 연산자, 마지막으로 눌렀던 숫자(두번째 피연산자) 를 계산한다.
• 연산을 위해 이미 Enter를 한번 눌렀기 때문에 (2)에서 previousNum이 할당되어 있다.

• 숫자 다음 Enter를 누를 경우는 operatorForAdvanced에 저장된 연산자가 없다면, Enter를 아무리 눌러도
아무런 연산도 하지않고 보여지는 화면도 그대로 유지시킨다.

 

✔️ 연산자 여러 번 누르면 1번만 인식 

✔️ JS를 활용하여 HTML 요소에 클래스 추가 구현

✔️ 연산 여러 번 가능하게 구현

if (action === 'operator') {
        target.classList.add('isPressed');  //누른 연산자 버튼에 클래스 추카
        if(operatorForAdvanced !== undefined && firstNum !== undefined 
            && previousKey !== 'operator' && previousKey !== 'calculate'){	//5+7*2처럼 연속 계산 할때
            display.textContent = calculate(firstNum, operatorForAdvanced, display.textContent);
        }
            console.log('연산자 ' + buttonContent + ' 버튼');
            operatorForAdvanced = buttonContent;    //누른 연산자를 저장
            previousKey = 'operator';   //이전에 누른 키가 연산자임을 저장
            firstNum = display.textContent; //연산자 전에 입력한 첫번째 값 저장
    }
    
if (action === 'number') {
     if(previousKey === 'operator'){	//이전에 누른 키가 연산자라면 숫자를 눌렀을 때 바뀐 색을 다시 원래대로 돌려줘야 함.
       let clickedOperator = document.querySelector('isPressed'); //isPressed 클래스가진 엘리먼트 받아오기 
       clickedOperator.classList.remove('isPressed'); // clickedOperator의 isPressed 클래스를 삭제해준다.
	}
        //...
}

script.js
0.01MB

• 연산자는 어차피 화면에 나타나지 않기 때문에 여러 번 누른다고 해도 상관 없다.

• target에 button이 들어가있고, 연산자 버튼을 누르면 element.classList.add()를 사용해서 눌린 버튼에 isPressed 클래스를 추가해준다.

• 이미 저장된 연산자와 첫 번째 피연산자가 있고(ex 1+), 이전 버튼이 연산자나 Enter가 아닌데(이전 버튼이 두 번째 피연산자 였고, 아직 연산을 안했다는 뜻) 연산자를 눌렀다.
-> 앞에 두 피연산자를 계산하고, 화면에 나타낸다. (화면에 나타내는 이유는 계산된 결과를 다음 연산에 사용하기 위해서)

📌 getElementByClassname(class이름) 
• 특정 class 이름을 가진 요소들을 가져와서 가져온 요소들을 배열로 반환한다.

📌 element.classList.add(class이름) 
• DOMtokenlist를 반환(공백으로 구분된 토큰 집합)
• 특정 element에 class를 추가한다.

 

✔️ 소수점 여러 번 누르면 1번만 인식

if (action === 'decimal') {
        if(previousKey !== 'decimal'){  //.이 연속으로 눌리는 경우 무시
            if(display.textContent === '0'){    //처음 .을 누를경우
                display.textContent = buttonContent;
            }
            else{
                if(previousKey === 'operator'){ //연산자 다음 바로 .누를 경우
                    display.textContent = buttonContent;
                }
                else{
                    display.textContent = display.textContent + buttonContent;  //숫자 뒤에 .을 누를경우
                }
            }
        }
        previousKey = 'decimal';
    }
• previousKey로 이전에 누른 키가 '.'인지 확인하고 '.'이 아닐 경우에만 .을 화면에 표시해준다.

 

✔️ CSS pseudo-class 사용하여 동적 버튼 구현 (:hover, :active, :focus) 

.clear__and__enter > button:active {
  box-shadow: 1px 1px 0 rgb(0,0,0,0.5);
  position: relative;
  top:2px;
}

.clear__and__enter > button:hover {
  background-color: #00e97c;
}

.button__row > button:active {
  box-shadow: 1px 1px 0 rgb(0,0,0,0.5);
  position: relative;
  top:2px;
}

.button__row > .number:hover {
  background-color: #f0f0f0;
}
• active는 버튼을 눌렀을 때 누른 효과가 나게 한다. (클릭하는 효과)

• hover는 버튼에 마우스를 갖다댔을 때 원래 색보다 색이 흐려지게 한다.

 

+ 12/27 css, js 코드 수정

 

화면 기록 2022-12-27 오후 1.28.35.mov
3.37MB