본문 바로가기
JavaScript

[JavaScript] 웹에서 동작하는 계산기 앱 만들기

by teamnova 2024. 11. 10.
728x90

안녕하세요.

오늘은 자바스크립트를 사용해 웹 기반 계산기 앱을 만들어보겠습니다.

목표

  • 자바스크립트를 사용해 브라우저에서 동작하는 계산기를 구현합니다.
  • 실시간으로 수식을 입력하고 중간 계산 결과를 표시하는 기능을 추가합니다.
  • 키보드 입력 및 백스페이스 기능을 지원하여 사용자 경험을 개선합니다.

 

1. index.html 파일 생성

먼저 html을 사용해 계산기 레이아웃을 구성합니다.

display 는 계산 결과를 표시하며, 각 버튼에는 자바스크립트 함수를 연결합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript Calculator</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="calculator">
        <div class="display" id="display">
            <div class="expression"></div>
            <div class="result"></div>
        </div>
        <div class="buttons">
            <button class="btn" onclick="clearDisplay()">C</button>
            <button class="btn" onclick="deleteLast()">⌫</button>
            <button class="btn" onclick="appendOperator('/')">÷</button>
            <button class="btn" onclick="appendOperator('*')">×</button>
            
            <button class="btn" onclick="appendNumber('7')">7</button>
            <button class="btn" onclick="appendNumber('8')">8</button>
            <button class="btn" onclick="appendNumber('9')">9</button>
            <button class="btn" onclick="appendOperator('-')">−</button>
            
            <button class="btn" onclick="appendNumber('4')">4</button>
            <button class="btn" onclick="appendNumber('5')">5</button>
            <button class="btn" onclick="appendNumber('6')">6</button>
            <button class="btn" onclick="appendOperator('+')">+</button>
            
            <button class="btn" onclick="appendNumber('1')">1</button>
            <button class="btn" onclick="appendNumber('2')">2</button>
            <button class="btn" onclick="appendNumber('3')">3</button>
            <button class="btn" onclick="appendDot()">.</button>
            <button class="btn equal" onclick="calculateResult()">=</button>
            
            <button class="btn zero" onclick="appendNumber('0')">0</button>
            
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

 

2. style.css 생성

css를 사용해 계산기의 스타일을 정의합니다.

grid-template-columns 속성을 사용해 버튼을 4열 구조로 배치하였으며, display 영역을 통해 결과를 표시합니다.

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: #f5f5f5;
    font-family: Arial, sans-serif;
}

.calculator {
    background-color: #333;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
    max-width: 400px;
    margin: auto;
}

.display {
    background-color: #444;
    color: white;
    padding: 20px;
    text-align: right;
    border-radius: 5px;
    margin-bottom: 20px;
    display: flex;
    flex-direction: column;
}

.expression {
    font-size: 2em;
    font-weight: bold;
    color: white;
    margin-bottom: 5px;
}

.result {
    font-size: 1.2em;
    color: #bbb;
    min-height: 1.5em; /* 최소 높이 지정 */
    transition: opacity 0.3s ease;
}

.buttons {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
}

.btn {
    background-color: #555;
    color: white;
    font-size: 1.5em;
    border: none;
    padding: 20px;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.2s;
}

.btn:hover {
    background-color: #777;
}

.equal {
    grid-column: span 2;
    background-color: #ff9500;
}

.zero {
    grid-column: span 2;
}

 

3. 자바스크립트 코드 작성

script.js 파일을 생성해서, 계산기 동작 로직을 구현합니다.

let expression = ''; // 전체 수식을 저장할 변수
let shouldResetScreen = false;

// 화면을 업데이트하는 함수
function updateDisplay() {
    const [currentExpression, currentResult] = document.getElementById('display').children;
    currentExpression.textContent = expression || '0';
    currentResult.textContent = calculateIntermediateResult() || '';
}

// 숫자 버튼 클릭 시 숫자를 추가하는 함수
function appendNumber(number) {
    if (shouldResetScreen) {
        expression = '';
        shouldResetScreen = false;
    }
    expression += number;
    updateDisplay();
}

// 연산자 버튼 클릭 시 수식 추가
function appendOperator(op) {
    if (expression === '') return;

    const lastChar = expression[expression.length - 1];
    if (['+', '-', '*', '/'].includes(lastChar)) {
        expression = expression.slice(0, -1) + op;
    } else {
        expression += op;
    }

    updateDisplay();
}

// 소수점 추가 함수
function appendDot() {
    const lastNumber = expression.split(/[\+\-\*\/]/).pop();
    if (!lastNumber.includes('.')) {
        expression += '.';
    }
    updateDisplay();
}

// 중간 계산 결과를 계산하는 함수
function calculateIntermediateResult() {
    try {
        if (expression && !['+', '-', '*', '/'].includes(expression[expression.length - 1])) {
            return eval(expression);
        }
    } catch {
        return '';
    }
    return '';
}

// = 버튼 클릭 시 전체 수식을 계산하는 함수
function calculateResult() {
    try {
        const result = eval(expression);
        expression = result.toString();
        shouldResetScreen = true;
        updateDisplay();
    } catch {
        expression = 'Error';
        updateDisplay();
    }
}

// 계산기 초기화 함수
function clearDisplay() {
    expression = '';
    updateDisplay();
}

// 백스페이스(⌫) 버튼을 누르면 마지막 입력 삭제
function deleteLast() {
    expression = expression.slice(0, -1);
    updateDisplay();
}

// 키보드 입력 지원
document.addEventListener('keydown', (event) => {
    const key = event.key;
    if (/[0-9]/.test(key)) appendNumber(key);
    else if (key === '.') appendDot();
    else if (key === '+') appendOperator('+');
    else if (key === '-') appendOperator('-');
    else if (key === '*') appendOperator('*');
    else if (key === '/') appendOperator('/');
    else if (key === 'Enter') calculateResult();
    else if (key === 'Backspace') deleteLast();
    else if (key === 'Escape') clearDisplay();
});