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";
}
}
});
어휴… 겨우겨우 구현했다… 그나마 페어란 같이 해서 다행이랄까… 서로 어려움, 고충들을 토로하면서 풀었다.
자바스크립트의 짜증나는 점은 이거다. || 랑 && 이 차이로 인해 작동이 될 수도 있고 안 될 수도 있다.
!display.textContent.includes(".") && previousKey !== "operator" 이거 처음에 ||로 썼다가 테스트케이스 다 fail 떠서 절망했었다…
특히 엔터 엔터 엔터 이런식으로 입력했을 때 구현하는거 참 어려웠다. 결국 firstNum을 쓰면 된다는걸 알고 약간 허무했다…
자바스크립트란 이런건가… 조금 더 공부 열심히 하자… 나 자신… 아무리 어렵더라도 힘내자…ㅎㅎ ㅠㅠ