syncsphere23's picture
⚙️ Functionality and Interactivity
c0129ea verified
Raw History Blame Contribute Delete
5.77 kB
class Calculator {
constructor(previousOperandTextElement, currentOperandTextElement) {
this.previousOperandTextElement = previousOperandTextElement;
this.currentOperandTextElement = currentOperandTextElement;
this.clear();
}
clear() {
this.currentOperand = '';
this.previousOperand = '';
this.operation = undefined;
}
delete() {
this.currentOperand = this.currentOperand.toString().slice(0, -1);
}
appendNumber(number) {
if (number === '.' && this.currentOperand.includes('.')) return;
this.currentOperand = this.currentOperand.toString() + number.toString();
}
chooseOperation(operation) {
if (this.currentOperand === '') return;
if (this.previousOperand !== '') {
this.compute();
}
this.operation = operation;
this.previousOperand = this.currentOperand;
this.currentOperand = '';
}
compute() {
let computation;
const prev = parseFloat(this.previousOperand);
const current = parseFloat(this.currentOperand);
if (isNaN(prev) || isNaN(current)) return;
switch (this.operation) {
case '+':
computation = prev + current;
break;
case '-':
computation = prev - current;
break;
case '×':
computation = prev * current;
break;
case '÷':
computation = prev / current;
break;
default:
return;
}
this.currentOperand = computation;
this.operation = undefined;
this.previousOperand = '';
}
getDisplayNumber(number) {
const stringNumber = number.toString();
const integerDigits = parseFloat(stringNumber.split('.')[0]);
const decimalDigits = stringNumber.split('.')[1];
let integerDisplay;
if (isNaN(integerDigits)) {
integerDisplay = '';
} else {
integerDisplay = integerDigits.toLocaleString('en', {
maximumFractionDigits: 0
});
}
if (decimalDigits != null) {
return `${integerDisplay}.${decimalDigits}`;
} else {
return integerDisplay;
}
}
updateDisplay() {
this.currentOperandTextElement.innerText =
this.getDisplayNumber(this.currentOperand);
if (this.operation != null) {
this.previousOperandTextElement.innerText =
`${this.getDisplayNumber(this.previousOperand)} ${this.operation}`;
} else {
this.previousOperandTextElement.innerText = '';
}
}
}
const numberButtons = document.querySelectorAll('[data-number]');
const operationButtons = document.querySelectorAll('[data-operation]');
const equalsButton = document.querySelector('[data-equals]');
const deleteButton = document.querySelector('[data-operation="DEL"]');
const allClearButton = document.querySelector('[data-operation="AC"]');
const previousOperandTextElement = document.getElementById('previous-operand');
const currentOperandTextElement = document.getElementById('current-operand');
const calculator = new Calculator(
previousOperandTextElement,
currentOperandTextElement
);
numberButtons.forEach(button => {
button.addEventListener('click', () => {
calculator.appendNumber(button.innerText);
calculator.updateDisplay();
button.classList.add('active');
setTimeout(() => button.classList.remove('active'), 150);
});
});
operationButtons.forEach(button => {
button.addEventListener('click', () => {
if (button.innerText === 'AC') {
calculator.clear();
} else if (button.innerText === 'DEL') {
calculator.delete();
} else {
calculator.chooseOperation(button.innerText);
}
calculator.updateDisplay();
button.classList.add('active');
setTimeout(() => button.classList.remove('active'), 150);
});
});
equalsButton.addEventListener('click', button => {
calculator.compute();
calculator.updateDisplay();
button.target.classList.add('active');
setTimeout(() => button.target.classList.remove('active'), 150);
});
// Keyboard support
document.addEventListener('keydown', (e) => {
if (e.key >= 0 && e.key <= 9) {
calculator.appendNumber(e.key);
calculator.updateDisplay();
const button = document.querySelector(`[data-number="${e.key}"]`);
if (button) {
button.classList.add('active');
setTimeout(() => button.classList.remove('active'), 150);
}
} else if (e.key === '.') {
calculator.appendNumber(e.key);
calculator.updateDisplay();
const button = document.querySelector('[data-number="."]');
if (button) {
button.classList.add('active');
setTimeout(() => button.classList.remove('active'), 150);
}
} else if (e.key === '+' || e.key === '-' || e.key === '*' || e.key === '/') {
let operation;
switch (e.key) {
case '*':
operation = '×';
break;
case '/':
operation = '÷';
break;
default:
operation = e.key;
}
calculator.chooseOperation(operation);
calculator.updateDisplay();
const button = document.querySelector(`[data-operation="${operation}"]`);
if (button) {
button.classList.add('active');
setTimeout(() => button.classList.remove('active'), 150);
}
} else if (e.key === 'Enter' || e.key === '=') {
calculator.compute();
calculator.updateDisplay();
equalsButton.classList.add('active');
setTimeout(() => equalsButton.classList.remove('active'), 150);
} else if (e.key === 'Backspace') {
calculator.delete();
calculator.updateDisplay();
deleteButton.classList.add('active');
setTimeout(() => deleteButton.classList.remove('active'), 150);
} else if (e.key === 'Escape') {
calculator.clear();
calculator.updateDisplay();
allClearButton.classList.add('active');
setTimeout(() => allClearButton.classList.remove('active'), 150);
}
});