Unit6 간단한 웹앱 만들기
계산기 기능을 JavaScript로 구현하기!
Bare Minimum Requirements는 소프트웨어가 그 역할을 하기에 필요한 최소한의 요구사항이다.
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이 리턴됩니다.
//숫자들을 정수로 전환!
let number1 = parseFloat(n1);
let number2 = parseFloat(n2);
//입력받은 operator에 맞게 계산 수행
if (operator === "+") {
result = number1 + number2;
} else if (operator === "-") {
result = number1 - number2;
} else if (operator === "*") {
result = number1 * number2;
} else {
//operator === "/"
result = number1 / number2;
}
// console.log(result);
//결과 string로 리턴
return String(result);
}
let numberbtn = 1; //1인경우 첫번째 숫자, 2인경우 두번째 숫자
let isOperator = false; //연산자가 눌렸는지
let isDecimal = false; //소수점이 눌렸는지
let isResult = false; //계산이 이미 진행된 상태인지
//과제1. 계산기 구현하기
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 (!isResult) {
if (action === "number") {
// 그리고 버튼의 클레스가 number이면
// 아래 코드가 작동됩니다.
if (numberbtn === 1 && !isDecimal) {
//첫번째 숫자가 눌리는 중이고 소수점이 없을 때
firstOperend.textContent = buttonContent;
} else if (numberbtn === 1 && isDecimal) {
//첫번째 숫자가 눌리는 중이고 소수점이 눌렸을 때
firstOperend.textContent += buttonContent;
} else {
//두번째 숫자
if (isOperator) {
if (!isDecimal) {
//두번째 숫자 눌리는 중이고 소수점이 없을 때
secondOperend.textContent = buttonContent;
} else {
//두번째 숫자 눌리는 중이고 소수점이 눌렸을 때
secondOperend.textContent += buttonContent;
}
}
}
}
if (action === "operator") {
if (!isOperator) {
operator.textContent = buttonContent;
isOperator = true;
numberbtn = 2;
isDecimal = false;
}
}
if (action === "decimal") {
if (numberbtn === 1) {
//첫번째 숫자가 소수점이 눌렀을 때
if (!isDecimal) {
firstOperend.textContent = firstOperend.textContent + ".";
isDecimal = true;
}
} else {
//두번째 숫자가 소수점이 눌렀을 때
if (!isDecimal) {
secondOperend.textContent = secondOperend.textContent + ".";
isDecimal = true;
}
}
}
if (action === "clear") {
firstOperend.textContent = 0;
operator.textContent = "+";
secondOperend.textContent = 0;
calculatedResult.textContent = 0;
numberbtn = 1;
isOperator = false;
isDecimal = false;
}
if (action === "calculate") {
let result = calculate(
firstOperend.textContent,
operator.textContent,
secondOperend.textContent
);
calculatedResult.textContent = result;
isResult = true;
}
}
//계산이 완료된 상태이면서 초기화 전 (넘버 버튼은 처리 X)
else {
if (action === "clear") {
firstOperend.textContent = 0;
operator.textContent = "+";
secondOperend.textContent = 0;
calculatedResult.textContent = 0;
numberbtn = 1;
isOperator = false;
isDecimal = false;
isResult = false;
}
if (action === "calculate") {
let result = calculate(
firstOperend.textContent,
operator.textContent,
secondOperend.textContent
);
calculatedResult.textContent = result;
isResult = true;
}
}
}
});
Bare Minimum Requirements를 넘어 User flow에 맞게 구현하기
//과제2. User flow에 따라 기능 구현하기
const display = document.querySelector(".calculator__display--for-advanced"); // calculator__display 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
let firstNum, operatorForAdvanced, previousKey, previousNum;
previousKey = false; //false:숫자버튼이 눌리면 false //true:연산자버튼이 눌리면 true
operatorForAdvanced = "";
let isResult2 = false;
let isDecimal2 = false; //소수점이 눌렸는지
let continuousOperation = false; //연속 연산인지
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")) {
// TODO : 계산기가 작동할 수 있도록 아래 코드를 수정하세요. 작성되어 있는 조건문과 console.log를 활용하시면 쉽게 문제를 풀 수 있습니다.
// 클릭된 HTML 엘리먼트가 button이면
// 계산되기 완료 전
if (action === "number") {
// 그리고 버튼의 클레스가 number이면
// 아래 코드가 작동됩니다.
if (isResult2) {
display.textContent = "0";
isResult2 = false;
firstNum = undefined;
previousNum = undefined;
}
console.log("숫자 " + buttonContent + " 버튼");
if (!previousKey) {
if (display.textContent === "0") {
if (!isDecimal2) {
// 처음 0인 상태 -> 소수점 입력이 안된 상태
display.textContent = buttonContent;
} else {
// 소수점 입력된 상태
display.textContent += buttonContent;
}
} else {
// 0이 아닌 경우 그냥 계속 옆에 추가
display.textContent += buttonContent;
}
} else {
if (!isDecimal2) {
// 처음 0인 상태 -> 소수점 입력이 안된 상태
display.textContent = buttonContent;
} else {
// 소수점 입력된 상태
display.textContent += buttonContent;
}
}
previousKey = false;
}
if (action === "operator") {
console.log("연산자 " + buttonContent + " 버튼");
if (!previousKey) {
if (firstNum !== undefined) {
console.log(previousNum);
//연속 연산
previousNum = display.textContent;
firstNum = calculate(firstNum, operatorForAdvanced, previousNum);
console.log(firstNum);
continuousOperation = true;
} else {
//첫 연산
firstNum = display.textContent;
}
previousKey = true;
isDecimal2 = false;
}
operatorForAdvanced = buttonContent;
console.log(operatorForAdvanced);
}
if (action === "decimal") {
console.log("소수점 버튼");
if (!isDecimal2) {
display.textContent += ".";
isDecimal2 = true;
}
if (previousKey || display.textContent === previousNum) {
display.textContent = "0.";
}
}
if (action === "clear") {
console.log("초기화 버튼");
//전부 초기화
display.textContent = 0;
isDecimal2 = false;
operatorForAdvanced = "";
continuousOperation = false;
firstNum = undefined;
previousNum = undefined;
}
if (action === "calculate") {
// console.log(operatorForAdvanced);
if (operatorForAdvanced !== "") {
if (isResult2) {
//enter 반복
firstNum = display.textContent;
let result = calculate(firstNum, operatorForAdvanced, previousNum);
display.textContent = `${result}`;
} else {
//enter 처음
if (!continuousOperation) {
//처음 enter & 연속 계산이 아닐때
console.log("계산 버튼");
previousNum = display.textContent;
let result = calculate(firstNum, operatorForAdvanced, previousNum);
display.textContent = `${result}`;
} else {
//처음 enter & 연속 계산일 때
previousNum = display.textContent;
let result = calculate(firstNum, operatorForAdvanced, previousNum);
display.textContent = `${result}`;
continuousOperation = false;
}
isResult2 = true;
}
}
}
}
});
오늘 하루종일 이 기능만.. ㅎㅎ JavaScript에 익숙해지려고 했는데 아직 조금 부족한 느낌이다.. ㅠ_ㅠ! 그래도 test 전부 통과해서 기분이 좋다! 처음에 설명 자료 참고를 까먹고 내 맘대로 구현하다가 다 갈아버린 ... 슬픈 기록 그래도 덕분에 '초심으로 돌아가기' 마인드를 배웠다. 다시 처음으로 돌아가야하는 날이 있을 수 있는데 , 그 때 너무 실망하지 않게 연습하는 기분! 아자자
아 그리고 아직 .. 코드가 많이 더러워서 올리기 창피하지만..! 고치고 싶은ㄷ..ㅍ_ㅍ 힘들다.. 내일 다시 생각해봐야겠당!