220630.code

Universe·2022년 6월 30일

code

목록 보기
2/13

HTML

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>계산기</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="calculator">
        <form name="forms">
            <input type="text" id="result" readonly>
            <input type="button" class="bt-num" id="bt-1" value="1">
            <input type="button" class="bt-num" id="bt-2" value="2">
            <input type="button" class="bt-num" id="bt-3" value="3">
            <input type="button" class="bt-option" id="plus" value="+">
            <input type="button" class="bt-num" id="bt-4" value="4">
            <input type="button" class="bt-num" id="bt-5" value="5">
            <input type="button" class="bt-num" id="bt-6" value="6">
            <input type="button" class="bt-option" id="minus" value="-">
            <input type="button" class="bt-num" id="bt-7" value="7">
            <input type="button" class="bt-num" id="bt-8" value="8">
            <input type="button" class="bt-num" id="bt-9" value="9">
            <input type="button" class="bt-option" id="multiply" value="*">
            <input type="button" class="bt-option" id="reset" value="AC">
            <input type="button" class="bt-num" id="bt-0" value="0">
            <input type="button" class="bt-option" id="calc" value="=">
            <input type="button" class="bt-option" id="divide" value="/">
        </form>
    </div>
<script src="script-1.js"></script>
</body>
</html>

CSS

*{
    margin:0;
    padding:0;
    box-sizing: border-box;
}

body {
    background-color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}


#calculator {
    width: 287px;
    border: 2px solid #333;
    border-radius: 10px;
    background-color:#005662;
    padding: 5px;;   
}

#calculator form {
    display: grid;
    grid-template-columns: repeat(4, 65px);
    grid-auto-rows: 65px;
    grid-gap: 5px;
}

#calculator form input {
    border: 2px solid #333;
    cursor: pointer;
    color: white;
    font-size: 30px;
}

#calculator form input:hover {
    box-shadow: 1px 1px 7px white;
    transition: 0.5s;
}

#calculator #result {
    grid-column: span 4;
    text-align: right;
    padding: 0 10px;
    background-color: #005662;
}

#calculator .bt-num {
    background-color: #00838f;
}

#calculator .bt-option {
    background-color: #4fb3bf;
}

JavaScript

let farmula = ''; // eval 계산을 하기위한 변수
let discNumber = false; // 연속된 연산자 판별. 초기값은 false
const $result = document.querySelector('#result'); // 결과값 input 창을 선택자로 가져와서 변수에 저장
const inputChar = (char) => { // inputChar 함수는
    return () => {
        if(discNumber === false){ // 이전에 연산자를 입력했는가?
            if(isNaN(char) === true){ // 입력받은 값이 숫자가 숫자가 아닌가? (연산자가 재입력 됐는가?)
                // 반응하지 않는다.
            } else {
                farmula += char; // 계산자 변수에 입력값을 추가
                $result.value += char; // input 창에 입력값을 추가하여 표시함
            }
        } else {
            farmula += char;
            $result.value += char;
        }

        if(isNaN(char) === true){ // 입력값이 숫자가 아니라면
            discNumber = false; // 연산자 판별 false
        } else {
            discNumber = true; // 숫자라면 연산자 판별을 true 로 변경한다
        }
    };
};
// 정말 중요하지만 몰랐던 이벤트리스너의 특성
// addEventListener('행동', '함수')
// addEventListener(type, listener);
// 반환값은 undefined ***
// 그렇기 때문에 함수안에 동작을 넣어주지 않으면 이상한 값을 실행함.
// 고차함수(high order function)로 함수안의 함수 처리 : 함수가 함수를 리턴함 // 함수간의 중복을 줄이기 위해 씀
// const inputChar = (char) => () => {} 이런식으로 return () => 을 생략하여 표현할 수도 있다.


const calculate = function() { // 계산하는 함수
    $result.value = eval(farmula); // 지금까지 입력받은 값을 eval로 계산하여 input 창에 출력
}
const erase = function() { // 초기화 함수
    $result.value = ''; // input 창을 초기화
    farmula = ''; // 계산을 위한 변수도 초기화
}

document.querySelector('#bt-0').addEventListener('click', inputChar('0'));
document.querySelector('#bt-1').addEventListener('click', inputChar('1'));
document.querySelector('#bt-2').addEventListener('click', inputChar('2'));
document.querySelector('#bt-3').addEventListener('click', inputChar('3'));
document.querySelector('#bt-4').addEventListener('click', inputChar('4'));
document.querySelector('#bt-5').addEventListener('click', inputChar('5'));
document.querySelector('#bt-6').addEventListener('click', inputChar('6'));
document.querySelector('#bt-7').addEventListener('click', inputChar('7'));
document.querySelector('#bt-8').addEventListener('click', inputChar('8'));
document.querySelector('#bt-9').addEventListener('click', inputChar('9'));
document.querySelector('#plus').addEventListener('click', inputChar('+'));
document.querySelector('#minus').addEventListener('click', inputChar('-'));
document.querySelector('#multiply').addEventListener('click', inputChar('*'));
document.querySelector("#divide").addEventListener('click', inputChar('/'));
document.querySelector('#reset').addEventListener('click', erase);
document.querySelector('#calc').addEventListener('click', calculate);

결과물




구현내용

  1. eval 함수를 이용한 식 계산기
  2. AC 버튼 클릭시 초기화
  3. 연산자 연속해서 입력할 수 없음
  4. 이뿌죠

추가 할 내용

  1. 키 입력에 관한 부분
    • 생각한 해결방안 : addEventListener 함수를 두번 써서 키 다운 입력을 받고 함수를 실행
    • 근데 같은 함수를 두번 쓰면 맛이없다
    • 해결책을 찾아보는 중

  2. 첫번째 입력을 *, / 는 받을 수 없게 설정
    - 생각한 해결방안 : 원래 if 중첩으로 해결하려고 해봤는데 잘 안됐다
    - 생각한 다른방안 : 판별하는 함수를 case, break 처리. 곱하기나 나누기가 첫 글자로 오면 무시
    - 구상은 했는데 어떻게 할 지 감이 잘 안온다.

profile
Always, we are friend 🧡

0개의 댓글