๐ฏ Learning Objectives
- ๐ง Understand the fundamental HTML structure for a calculator interface.
- โ๏ธ Implement JavaScript event listeners for user interactions.
- ๐งฎ Develop robust arithmetic logic to perform calculations.
- ๐ Master DOM manipulation to update the calculator display dynamically.
- ๐ Debug common issues encountered during web project development.
๐ ๏ธ Materials Needed
- ๐ป A code editor (e.g., VS Code, Sublime Text).
- ๐ A modern web browser (e.g., Chrome, Firefox).
- ๐ Basic understanding of HTML, CSS, and JavaScript syntax.
โก Warm-up Activity (5 mins)
- ๐ค Discuss with a partner: What are the essential buttons and display elements a calculator needs?
- ๐ Jot down a simple flowchart of how a user might interact with a calculator (e.g., 'Press 5' -> 'Press +' -> 'Press 3' -> 'Press =').
- ๐ก Brainstorm potential challenges in handling multiple operations or decimal numbers.
๐ก Main Instruction: Building Your JavaScript Calculator
Let's dive into creating a fully functional JavaScript calculator. We'll break it down into three core parts: HTML for structure, CSS for styling (briefly), and JavaScript for all the logic.
๐ HTML Structure (`index.html`)
We'll create a container for our calculator and individual divs for the display and buttons.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Calculator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="calculator">
<div class="display">0</div>
<div class="buttons">
<button class="clear">AC</button>
<button class="operator">÷</button>
<button class="operator">×</button>
<button class="backspace">⌫</button>
<button>7</button>
<button>8</button>
<button>9</button>
<button class="operator">-</button>
<button>4</button>
<button>5</button&n>
<button>6</button>
<button class="operator">+</button>
<button>1</button>
<button>2</button>
<button>3</button>
<button class="equals">=</button>
<button class="zero">0</button>
<button class="decimal">.</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
๐จ CSS Styling (`style.css` - Key Concepts)
We'll use CSS Grid for a responsive button layout and basic styling for readability.
- ๐ Grid Layout: Apply `display: grid;` to the `.buttons` container and define `grid-template-columns` for a 4-column layout.
- ๐จ Basic Styling: Add `background-color`, `padding`, `border-radius` for the calculator body and buttons.
- โ๏ธ Display: Style the `.display` to show a large, right-aligned number.
โ๏ธ JavaScript Logic (`script.js`)
This is where the magic happens! We'll manage state, handle user input, and perform calculations.
const display = document.querySelector('.display');
const buttons = document.querySelectorAll('.buttons button');
let currentInput = '0';
let operator = null;
let previousInput = '';
let resetDisplay = false;
function updateDisplay() {
display.textContent = currentInput;
}
function appendNumber(number) {
if (currentInput === '0' || resetDisplay) {
currentInput = number;
resetDisplay = false;
} else {
currentInput += number;
}
updateDisplay();
}
function appendDecimal() {
if (resetDisplay) {
currentInput = '0.';
resetDisplay = false;
} else if (!currentInput.includes('.')) {
currentInput += '.';
}
updateDisplay();
}
function chooseOperator(nextOperator) {
if (operator && !resetDisplay) {
calculate();
}
previousInput = currentInput;
operator = nextOperator;
resetDisplay = true;
}
function calculate() {
let result;
const prev = parseFloat(previousInput);
const current = parseFloat(currentInput);
if (isNaN(prev) || isNaN(current)) return;
switch (operator) {
case '+':
result = prev + current;
break;
case '-':
result = prev - current;
break;
case '×':
result = prev * current;
break;
case '÷':
result = prev / current;
break;
default:
return;
}
currentInput = result.toString();
operator = null;
resetDisplay = true;
updateDisplay();
}
function clearAll() {
currentInput = '0';
operator = null;
previousInput = '';
resetDisplay = false;
updateDisplay();
}
function backspace() {
if (currentInput.length > 1 && !resetDisplay) {
currentInput = currentInput.slice(0, -1);
} else {
currentInput = '0';
resetDisplay = false;
}
updateDisplay();
}
buttons.forEach(button => {
button.addEventListener('click', () => {
const buttonText = button.textContent;
if (button.classList.contains('clear')) {
clearAll();
} else if (button.classList.contains('operator')) {
chooseOperator(buttonText);
} else if (button.classList.contains('equals')) {
calculate();
} else if (button.classList.contains('decimal')) {
appendDecimal();
} else if (button.classList.contains('backspace')) {
backspace();
} else {
appendNumber(buttonText);
}
});
});
updateDisplay(); // Initialize display
- ๐๏ธ DOM Selection: `document.querySelector` and `document.querySelectorAll` are used to select the display and all buttons.
- ๐ State Variables: `currentInput`, `previousInput`, `operator`, and `resetDisplay` keep track of the calculator's current state.
- ๐ Event Listeners: A `forEach` loop iterates over all buttons, attaching a `click` event listener to each.
- โ `appendNumber(number)`: Handles adding digits to the `currentInput`, ensuring '0' is replaced and not just concatenated.
- โ๏ธ `chooseOperator(nextOperator)`: Stores the selected operator and the `currentInput` as `previousInput`, then prepares for the next number.
- ๐งฎ `calculate()`: Parses `previousInput` and `currentInput` as floats and performs the arithmetic based on the stored `operator`. It handles addition ($A + B$), subtraction ($A - B$), multiplication ($A \times B$), and division ($A \div B$).
- ๐งน `clearAll()`: Resets all state variables to their initial values.
- โฌ
๏ธ `backspace()`: Removes the last character from `currentInput`, or resets to '0' if only one character remains.
- ๐ฅ๏ธ `updateDisplay()`: Updates the `textContent` of the display element with the `currentInput`.
โ
Assessment: Practice Challenges
Test your understanding and extend the calculator's functionality with these challenges:
- ๐งช Error Handling: How would you prevent division by zero? Modify the `calculate()` function to display an 'Error' message.
- ๐ข Keyboard Support: Implement keyboard event listeners so users can operate the calculator using their keyboard.
- ๐จ Visual Feedback: Add a visual effect (e.g., a brief color change) when a button is clicked.
- ๐งฎ Chain Operations: Ensure the calculator correctly handles consecutive operations (e.g., `5 + 3 - 2 =`).
- ๐ Percentage Button: Add a '%' button that divides the `currentInput` by 100.
- +/- Sign Change: Implement a '+/-' button to toggle the sign of the `currentInput`.
- ๐พ Memory Functions: Add 'M+', 'M-', 'MR', 'MC' buttons for memory storage.