-
자바스크립트 계산기 만들기 1: 계산기 꾸미기, 계산식 입력자바스크립트 2020. 3. 30. 23:38
css 그리드와 자바스크립트를 이용해서 계산기 만들기
계산기 개발 순서
1. 계산기 뼈대 만들기
2. 계산기 꾸미기
3. 버튼 클릭 시 input에 텍스트 추가
4. AC 기능 구현
5. 계산 기능 구현 (=버튼)
6. 예외 처리
계산기 뼈대 만들기
필요한 태그
-
숫자, 연산자를 클릭할 수 있는 <button />
-
<button />에 그리드를 적용하기 위한 <div />
-
버튼 클릭 시 값을 입력받을 <input />
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Calculator</title> <link rel="stylesheet" href="style.css"> </head> <body> <main> <input type="text" disabled> <div class="button-wrap"> <button>AC</button> <button>÷</button> <button>7</button> <button>8</button> <button>9</button> <button>×</button> <button>4</button> <button>5</button> <button>6</button> <button>-</button> <button>1</button> <button>2</button> <button>3</button> <button>+</button> <button>0</button> <button>.</button> <button>=</button> </div> </main> </body> </html>
계산기 꾸미기
그리드 레이아웃으로 버튼 정렬
/* style.css */ main { width: 300px; } .button-wrap { display: grid; /* 한 줄에 4개씩, 모두 동일한 비율 적용(1:1:1:1) */ grid-template-columns: repeat(4, 1fr); }
AC, 0 버튼 크기 조절
<main> <input type="text" disabled> <div class="button-wrap"> <!-- ac 클래스 추가 --> <button class="ac">AC</button> <button>÷</button> <button>7</button> <button>8</button> <button>9</button> <button>×</button> <button>4</button> <button>5</button> <button>6</button> <button>-</button> <button>1</button> <button>2</button> <button>3</button> <button>+</button> <!-- zero 클래스 추가 --> <button class="zero">0</button> <button>.</button> <button>=</button> </div> </main>
... .ac { /* 첫 번째 선부터 4번째 선까지 지정 */ grid-column: 1/4; } .zero { /* 첫 번째 선부터 3번째 선까지 지정 */ grid-column: 1/3; }
input 태그 스타일 설정
/* style.css */ * { box-sizing: border-box; color: white; } input, button { height: 70px; outline: none; } input { width: 100%; text-align: right; border: none; background: #5B5B5D; padding-right: 1rem; font-size: 3rem; }
버튼 태그 스타일 설정
button { background: #828284; border: 1px solid #454448; font-size: 2rem; } /* nth-child(4n+2): 4번째 요소마다 스타일을 적용하는데 처음에만 두번째에 적용 */ button:nth-child(4n+2), button:last-child { background-color: orange; } button:hover { opacity: .5; } .ac { grid-column: 1/4; background: #6A6A6C; } .zero { grid-column: 1/3; }
버튼 클릭 시 input에 추가
버튼 클릭 시 data-type에 따라 동작을 다르게 처리하기 위해 숫자 버튼을 제외하고 data-type 속성 추가
- AC버튼 : data-type="ac"
- 연산자 버튼 : data-type="operator"
- = 버튼 : data-type="equals"
<main> <input type="text" value="0" disabled> <div class="button-wrap"> <button data-type="ac" class="ac">AC</button> <button data-type="operator">÷</button> <button>7</button> <button>8</button> <button>9</button> <button data-type="operator">×</button> <button>4</button> <button>5</button> <button>6</button> <button data-type="operator">-</button> <button>1</button> <button>2</button> <button>3</button> <button data-type="operator">+</button> <button class="zero">0</button> <button>.</button> <button data-type="equals" class="equals">=</button> </div> </main>
script.js 파일을 만들고 버튼과 input 태그를 가져와서 변수에 담기
const buttons = document.querySelectorAll('button') const displayElement = document.querySelector('input')
html 파일에 script.js 연결
<body> <main> <!-- ... --> </main> <script src="script.js"></script> </body>
Calculator 클래스 만들고 인스턴스 생성
class Calculator { constructor(displayElement) { this.displayElement = displayElement this.displayContent = '' } } const buttons = document.querySelectorAll('button') const displayElement = document.querySelector('input') const calculator = new Calculator(displayElement)
addEventListener로 모든 버튼에 클릭 이벤트를 연결하고 switch문으로 data-type에 따라 버튼 구분
// ... const buttons = document.querySelectorAll('button') const displayElement = document.querySelector('input') const calculator = new Calculator(displayElement) buttons.forEach(button => { button.addEventListener('click', () => { switch (button.dataset.type) { case 'operator': console.log('operator') break case 'ac': console.log('ac') break case 'equals': console.log('equals') break default: console.log('number') break } }) })
숫자 버튼을 클릭할 때마다 displayContent 속성에 숫자가 추가되고 input에도 표시되도록 appendNumber, updateDisplay 메서드 추가
switch문의 default에서 추가한 메서드 호출
class Calculator { constructor(displayElement) { this.displayElement = displayElement this.displayContent = '' } appendNumber(number) { this.displayContent += number } updateDisplay() { this.displayElement.value = this.displayContent } } const buttons = document.querySelectorAll('button') const displayElement = document.querySelector('input') const calculator = new Calculator(displayElement) buttons.forEach(button => { button.addEventListener('click', () => { switch (button.dataset.type) { case 'operator': console.log('operator') break case 'ac': console.log('ac') break case 'equals': console.log('equals') break default: calculator.appendNumber(button.innerText) calculator.updateDisplay() break } }) })
마찬가지로 클래스에 appendOperator 메서드 추가 후 연산자 버튼 클릭 시 호출되도록 연결
class Calculator { constructor(displayElement) { this.displayElement = displayElement this.displayContent = '' } appendNumber(number) { this.displayContent += number } appendOperator(operator) { this.displayContent += operator } updateDisplay() { this.displayElement.value = this.displayContent } } const buttons = document.querySelectorAll('button') const displayElement = document.querySelector('input') const calculator = new Calculator(displayElement) buttons.forEach(button => { button.addEventListener('click', () => { switch (button.dataset.type) { case 'operator': calculator.appendOperator(button.innerText) calculator.updateDisplay() break //... } }) })
AC 기능 구현
AC 버튼을 클릭하면 입력했던 게 초기화되도록 클래스에 clear 메서드 추가 후 AC 버튼과 연결
class Calculator { // ... clear() { this.displayContent = '' this.displayElement.value = 0 } } const buttons = document.querySelectorAll('button') const displayElement = document.querySelector('input') const calculator = new Calculator(displayElement) buttons.forEach(button => { button.addEventListener('click', () => { switch (button.dataset.type) { case 'ac': calculator.clear() break //... } }) })
constructor에서도 clear 메서드를 호출하도록 수정
class Calculator { constructor(displayElement) { this.displayElement = displayElement this.clear() } }
html에서 input 태그의 value 속성은 더 이상 필요 없으니 제거
<!--<input type="text" value="0" disabled>--> <input type="text" disabled>
'자바스크립트' 카테고리의 다른 글
자바스크립트 계산기 만들기 2: 계산기능 구현, 예외처리 (4) 2020.04.10 -