같은 행의 버튼 라인 별로 태그박스를 감싸주도록 했다.
위 계산기 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 코드
.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; }
자바스크립트로 계산기 기능 구현하기
'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. 변수를 활용하여 기능 구현의 다양한 상황에 맞게 꺼내 쓸 수 있다는 점!