버튼이 잘 눌렸는지 확인 -> 클릭시 console 창 확인
버튼은 기본적으로 ( 숫자, 연산자 + - * /, 소수점. , 계산 Enter , 초기화 AC ) 으로 구성
- 소숫점 버튼 클릭시 console 창에 '소숫점 버튼' 출력
const buttons = calculator.querySelector('.calculator__buttons'); // calculator__buttons 엘리먼트와, 그 자식 엘리먼트의 정보 => 버튼들의 정보
buttons.addEventListener('click', function (event) {
//버튼을 눌렀을 경우
const target = event.target; // 클릭된 HTML 엘리먼트의 정보가
const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보
const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보
if (target.matches('button')) {
//클릭된 html 엘리먼트가 button과 일치할 경우
if (action === 'decimal') {
//button의 class 명이 decimal 인 경우
//console 창에 '소수점 버튼' 출력
console.log('소수점 버튼');
}
}
기본 계산 기능 구현하기 -> 두 숫자의 사칙연산
textContent
: 엘리먼트의 text 값
const firstOperend = document.querySelector('.calculator__operend--left');//calculator__operend--left 엘리먼트와, 그 자식 엘리먼트의 정보 = 첫번째 칸
const secondOperend = document.querySelector('.calculator__operend--right'); // calculator__operend--right 엘리먼트와, 그 자식 엘리먼트의 정보 = 두번째 칸
buttons.addEventListener('click', function (event) {
//버튼을 눌렀을 경우
const target = event.target; // 클릭된 HTML 엘리먼트의 정보가
const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보
const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보
if (target.matches('button')) {
//클릭된 html 엘리먼트가 button과 일치할 경우
if (action === 'number') {
//button의 class명이 number인 경우
if(firstOperend.textContent === '0'){
//현재 첫번째 칸의 '0'인 경우(기본값)에 클릭된 텍스트 정보인 buttonContent 값으로 변경
firstOperend.textContent = buttonContent;
}else{
//현재 첫번째 칸의 '0'인 아닌 경우(이미 바꾸어진 값)에
secondOperend.textContent = buttonContent;
}
}
}
}
const operator = document.querySelector('.calculator__operator');//calculator__operator 엘리먼트와, 그 자식 엘리먼트의 정보 = 연산자 칸
const calculatedResult = document.querySelector('.calculator__result'); // calculator__result 엘리먼트와, 그 자식 엘리먼트의 정보 = 세번째 칸 = 결과값
function calculate(n1, operator, n2) {
//string 변수인 첫번째 칸 값, 연산자 값, 두번째 칸 값 을 매개변수로 가짐
let result = 0;
//연산자의 종류에 따라 문자열을 숫자형으로 바꿔준 후 계산한 값을 result로 받아 반환
if(operator === '+'){
result = Number(n1) + Number(n2);
}else if(operator === '-'){
result = Number(n1) - Number(n2);
}else if(operator === '*'){
result = Number(n1) * Number(n2);
}else if(operator === '/'){
result = Number(n1) / Number(n2);
}
return result;
}
buttons.addEventListener('click', function (event) {
//버튼을 눌렀을 경우
const target = event.target; // 클릭된 HTML 엘리먼트의 정보가
const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보
const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보
if (target.matches('button')) {
//클릭된 html 엘리먼트가 button과 일치할 경우
if (action === 'calculate') {
//button의 class 명이 calculate 인 경우
console.log('계산 버튼');
calculatedResult.textContent = calculate(firstOperend.textContent, operator.textContent, secondOperend.textContent);
// calculate 함수로 결과값을 반환한 값으로 세번째 결과값에 변경
}
}
}
buttons.addEventListener('click', function (event) {
//버튼을 눌렀을 경우
const target = event.target; // 클릭된 HTML 엘리먼트의 정보가
const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보
const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보
if (target.matches('button')) {
//클릭된 html 엘리먼트가 button과 일치할 경우
if (action === 'clear') {
//button의 class명이 number인 경우
console.log("초기화 버튼");
firstOperend.textContent = '0';
secondOperend.textContent = '0';
calculatedResult.textContent = '0';
operator.textContent = '+';
}
}
}
display : 계산 혹은 숫자가 보이는 곳 // 설정하기 위해서는 'diplay.textContent = 값' 으로 설정
buttonContent : 현재 클릭한 값
//밑의 변수의 초기화는 undefined로 설정
firstNum : 첫번째 피연산자 값
operatorForAdvanced: 연산자 값
previousNum : 두번째 피연산자 값
previousKey : 이전의 클릭한 action 종류 값//=> 이 변수를 이용하여 연속값인지 확인
숫자버튼 누르고 화면에 숫자를 입력하기
Enter 버튼 눌러 계산하고 AC 버튼으로 초기화 시키기
if (action === 'number') {// 버튼의 종류가 number 인 경우
if(firstNum === undefined){
//첫번째 피연산자값이 설정되지 않은 경우
firstNum = buttonContent;
display.textContent = firstNum;
//클릭한 그 숫자값이 곧 첫번째 피연산자값
}else{
if(operatorForAdvanced === undefined){
//첫번째 피연산자 값이 설정되었지만, 연산자 값이 아직 설정되지 않았기 때문에 첫번째 피연산자 값에 이어붙어줘야 함
firstNum = firstNum.concat(buttonContent); //혹은 firstNum += buttonContent;
display.textContent = firstNum;
}else{//첫번째 피연산자 값과 연산자 값도 모두 설정된 후 숫자를 클릭했을 경우
if(previousNum === undefined){
//두번째 피연산자를 처음으로 설정할 경우
previousNum = buttonContent;
}else{//앞서 설정된 두번째 피연선자 값에 추가로 덧붙여 줌
previousNum = previousNum.concat(buttonContent);
}
display.textContent = previousNum;
}
}
previousKey = 'number';
}
function calculate(n1, operator, n2) {
let result = 0;
//1 . 실수인지 정수인지 판별
if(!Number.isInteger(n1) || !Number.isInteger(n2)){
//실수인 경우 : n1 나 n2 하나라도 실수인 경우 => number 타입 실수로 변환
n1 = parseFloat(n1);
n2 = parseFloat(n2);
}else{
//정수인 경우: number 타입 정수로 변환
n1 = parseInt(n1);
n2 = parseInt(n2);
}
//2. 형변환으로 만든어진 수들로 연산자의 종류에 따라 계산
if(operator === '*'){
result = n1 + n2;
}else if(operator === '-'){
result = n1 - n2;
}else if(operator === '*'){
result = n1 * n2;
}else if(operator === '/'){
result = n1 / n2;
}
return result;
}
계산기 특이 작동
3 * * * * * 3 Enter => 3 (아무일 x)
3 * 3 Enter Enter Enter Enter => 243(3*3=9*3=27*3=243) => 즉, 결과값과 두번째 피연산자가 연산작용하여 결과값 도출
3 * Enter => 9 (3*3=9) => 즉, 첫번째 피연산자가 두번째 피연산자로 대체되어 연산작용하여 결과값 도출
if (action === 'calculate') {
if(previousKey === 'calculate'){
//연속 엔터인 경우
//첫번째 엔터의 결과값에 연산자와 두번째피연산자를 이용하여 다시 결과값 도출하여 화면에 출력
let res = calculate(display.textContent, operatorForAdvanced, previous);
display.textContent = res;
}else{
//연속 엔터 아닐 경우
if(previousKey === 'operator'){
//이전의 키가 연산자일 경우 => 첫번째 피연산자와 연산자로만 계산
let res = calculate(firstNum, operatorForAdvanced, firstNum);
display.textContent = res;
}else{
//아닌 경우 => 평범한 상황이므로 첫번째 피연산자와 두번째 피연산자와 연산자로만 계싼
let res = calculate(firstNum, operatorForAdvanced, previousNum);
display.textContent = res;
}
}
previousKey = 'calculate';
}
100..1252 => 100.1252 => 덧붙이지 않고 그대로 유지 => 아무런 명령 x
if (action === 'decimal') {
if(previousKey !== 'decimal'){
//연속 소수점키가 아닌 경우 => 소수점키를 처음 붙이는 경우
if(firstNum === undefined){
//첫번째 피연산자 값이 지정되지 않은 경우 => 0.으로 설정후 화면출력
firstNum = '0.';
display.textContent = firstNum;
}else{//첫번째 피연산자 값이 지정된 경우
if(operatorForAdvanced === undefined){
//연산자가 설정되지 않은 경우 = 두번째 피연산자도 어차피 설정되지 않음 => 아직 첫번째 피연산자 값을 설정 중 => 첫번째 피연자 값에 .을 덧붙여줌
//두번째 값이 지정되지 않은 경우 => 첫번째 피연산자 값에 .을 덧붙여줌
firstNum = firstNum.concat('.'); //혹은 firstNum += '.';
display.textContent = firstNum;
}else{//연산자가 설정된 경우 두번째 피연산자를 설정해줘야하는 차례
if(previousNum === undefined){
//두번째 피연산자가 설정되지 않은 경우 => 0.으로 설정 후 화면 출력
previousNum = '0.';
}else{
//두번째 피연산자 값이 지정된 경우 => 두번째 피연산자 값에 .을 덧붙여 줌
previousNum = previousNum.concat('.');// 혹은 previousNum += '.';
}
display.textContent = previousNum;
}
}
}
previousKey = 'decimal';
}
100 . . 1 2 5 2 + 1 2 + 1 5 - - 2 3 - 1 4 4 2 / 2 3 / / 1 2 * 2 3 Enter => 100.1252 + 12 + (112.1252 출력) + 15 -(127.1252 출력) - (연속 연산자는 아무일x) 23 - (104.1252 출력) 1442 / (-1337.8748출력) 23 / (-58.16846956521739출력) / 12 * (-4.847372463768116출력) 23 Enter (-111.48956666666668 최종출력
if (action === 'operator'){
//첫번째 피연산자와 두번째 피연산자, 연산자가 모두 설정이 된 후에 누른 버튼이 operator 인 경우
//=> 먼저 계산해준 후, 값을 화면에 출력하고 첫번째 피연산자는 결과값으로 갱신, 두번째 피연산자는 초기화, 연산자는 눌러진 연산자 버튼 값을 새로 갱신
if(previousNum !== undefined){
//두번째 피연산자가 설정이 되어있는 경우
//= 즉, 첫번째 피연산자와 두번째 피연산자, 연산자가 모두 설정이 된 후 라는 말
let res = calculate(firstNum, operatorForAdvanced, previousNum);
firstNum = res;
display.textContent = res;
previousNum = undefined;
}
operatorForAdvanced = buttonContent; //연산자 갱신은 모두 해당
previousKey = 'operator';
}