IT공부/JAVASCRIPT

[JavaScript 기초] 계산기 구현

재삐 2024. 2. 6. 00:03
반응형

 

JavaScript를 이용하여 계산기를 구현 해 보았습니다.

 

우선 HTML과 CSS로 UI를 꾸밉니다.

 

목차

1) html 코드
2) css 코드
3) javascript 코드

 

 

1) HTML 코드

div.wrap으로 input 태그와 button.btn 태그들을 감쌌습니다.

특수문자 코드표로 작성되었습니다.

body 태그 안의 내용만 적었습니다.

  <!-- body 태그 안의 내용 -->
  <div class="wrap">
    <input type="text" id="formula" readonly> <!-- readonly : text 직접 입력 불가능하게 -->
    <button class="btn">7</button>
    <button class="btn">8</button>
    <button class="btn">9</button>
    <button class="btn">&#47;</button> <!-- / -->
    <button class="btn">4</button>
    <button class="btn">5</button>
    <button class="btn">6</button>
    <button class="btn">&#42;</button> <!-- * -->
    <button class="btn">1</button>
    <button class="btn">2</button>
    <button class="btn">3</button>
    <button class="btn">&#45;</button> <!-- - -->
    <button class="btn">0</button>
    <button class="btn" id="all-clear">AC</button>
    <button class="btn">&#43;</button> <!-- + -->
    <button class="btn" id="result">&#61;</button> <!-- = -->
  </div>

 

2) CSS 코드

* {
  margin: 0;
  /* outline: solid; */
}

.wrap {
  /* --- grid로 레이아웃 구성 --- */
  display: grid;
  grid-template-columns : repeat(4, 1fr);
  grid-template-rows : repeat(5, 1fr);
  gap : 10px 10px;
  /* -------------------------------- */
  width: 400px;
  height: 400px;
  margin: 100px auto;
  border : 5px ridge;
  padding : 70px 30px 20px 30px;
  box-shadow: 8px 8px 10px gray;
  background-color: rgb(199, 199, 199);
}

/* 계산 결과 필드 */
.wrap #formula {
  grid-column: 1 / 5; /* grid 최상단 행 차지*/
  font-size: 1.6rem;
  font-weight : bold;
  text-align: right;
  padding: 0 3vw;
  
}

/* btn 폰트 크기 */
.wrap .btn {
  font-size: 1.4rem;
}

/* btn 클릭한거 색깔 칠하기 */
.wrap .btn.on {
  background-color: yellow;
  box-shadow: 3px 3px 5px gray inset;
}

/* Erorr시 버튼 비활성화 */
.wrap .btn.err {
  pointer-events: none;
  opacity: 0.5;
}

 

3) javascript 코드

더보기
// 변수
const $formula = document.getElementById('formula');
const $btns = document.querySelectorAll('.btn');
const $allClear = document.getElementById('all-clear');
const $result = document.getElementById('result');
const $wrap = document.querySelector('.wrap');

// console.log(Object.prototype.toString.call($btns));
// ★$formula에 값 추가
$btns.forEach(ele => ele.addEventListener('click', evt => {
    // console.log(evt);
    if (evt.target.textContent !== 'AC' && evt.target.outerText !== '=') {
      $formula.value += evt.target.textContent;
      $formula.style.color = 'inherit';
    }
    if ($formula.value.length > 25) {
      $formula.value = '자리수 초과';
      $formula.style.color = 'red';
      $btns.forEach(ele => {
        if (ele.target != 'AC' && ele.id !== 'all-clear') {
          ele.classList.add('err');
        }
      });
    }
  }));

// ★AC버튼 클릭시 계산결과 필드 초기화
$allClear.addEventListener('click', evt => {
  $formula.value = '';
  $formula.style.color = 'inherit';
  $btns.forEach(ele => {
    ele.classList.remove('err');
  });
});

// ★'='버튼 클릭시 계산결과 출력
$result.addEventListener('click', evt => {
  try {
    if ($formula.value) {
      // Function 생성자를 사용하여 문자열을 함수로 변환하고 실행
      var calculate = new Function('return ' + $formula.value);
      $formula.value = calculate();
      $formula.style.color = 'blue';
    }
  } catch(error) {
    $formula.value = 'Error';
    $formula.style.color = 'red';
    $btns.forEach(ele => {
      if (ele.target != 'AC' && ele.id !== 'all-clear') {
        ele.classList.add('err');
      }
    });
  }
});

// ★클릭한 버튼만 배경 색상이 노란색으로 변경
$wrap.addEventListener('click', evt => {
  $btns.forEach(ele => {
    if (evt.target === ele) { // $wrap 영역에서 버튼을 누른거면 add('on')
      ele.classList.add('on'); // 해당 btn 태그 속성 class이름 on 추가
    } else {
      ele.classList.remove('on'); // wrap 영역에서 click 안된것들은 class이름 on 제거
    }
  });
});

 


Copyright ⓒ. JaePPy All rights reserved.

usopp1004@naver.com

반응형