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 1
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-delete]')
const allClearButton = document.querySelector('[data-all-clear]')
const previousOperandTextElement = document.querySelector('[data-previous-operand]')
const currentOperandTextElement = document.querySelector('[data-current-operand]')
const calculator = new Calculator(previousOperandTextElement, currentOperandTextElement)
numberButtons.forEach(button => {
button.addEventListener('click', () =>{
calculator.appendNumber(button.innerText)
calculator.updateDisplay()
})
})
operationButtons.forEach(button => {
button.addEventListener('click', () =>{
calculator.chooseOperation(button.innerText)
calculator.updateDisplay()
})
})
equalsButton.addEventListener('click', button => {
calculator.compute()
calculator.updateDisplay()
})
allClearButton.addEventListener('click', button => {
calculator.clear()
calculator.updateDisplay()
})
deleteButton.addEventListener('click', button => {
calculator.delete()
calculator.updateDisplay()
})
document.onkeyup = e => {
if(e.key == "1") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "2") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "3") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "4") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "5") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "6") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "7") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "8") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "9") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "0") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == ".") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if(e.key == "+" || e.key == "-" || e.key == "*" || e.key == "/") {
if(e.key == "/"){
let conversion = e.key;
conversion = "÷";
calculator.chooseOperation(conversion)
calculator.updateDisplay()
} else{
calculator.chooseOperation(e.key)
calculator.updateDisplay()
}
} else if(e.key == "Enter") {
equalsButton.click()
} else if(e.key == "Backspace") {
calculator.delete()
calculator.updateDisplay()
}
}
*, *::before, *::after {
box-sizing: border-box;
font-family: Gotham Rounded, sans-serif;
font-weight: normal;
}
body {
padding: 0;
margin: 0;
background: linear-gradient(to right, #00AAFF, #00FF6C);
}
.calculator-grid {
display: grid;
justify-content: center;
align-content: center;
min-height: 100vh;
grid-template-columns: repeat(4,100px);
grid-template-rows: minmax(120px, auto) repeat(5,100px);
}
.calculator-grid > button {
cursor: pointer;
font-size: 2rem;
border: 2px solid black;
outline: none;
background-color: rgba(255, 255, 255, .75)
}
.calculator-grid > button:hover {
background-color: rgba(255, 255, 255, .9);
}
.span-two {
grid-column: span 2;
}
.output {
grid-column: 1/-1;
background-color: rgba(0,0,0,.75);
display: flex;
align-items: flex-end;
justify-content: space-around;
flex-direction: column;
padding: 10px;
word-wrap: break-word;
word-break: break-all;
}
.output .previous-operand {
color: rgba(255, 255, 255,.75);
font-size: 1.5rem;
}
.output .current-operand {
color: white;
font-size: 2.5rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculator</title>
<link href="styles.css" rel="stylesheet">
<script src="script.js" defer></script>
</head>
<body>
<div class="calculator-grid">
<div class="output">
<div data-previous-operand class="previous-operand"></div>
<div data-current-operand class="current-operand"></div>
</div>
<button data-all-clear class="span-two">AC</button>
<button data-delete>DEL</button>
<button data-operation>÷</button>
<button data-number>1</button>
<button data-number>2</button>
<button data-number>3</button>
<button data-operation>*</button>
<button data-number>4</button>
<button data-number>5</button>
<button data-number>6</button>
<button data-operation>+</button>
<button data-number>7</button>
<button data-number>8</button>
<button data-number>9</button>
<button data-operation>-</button>
<button data-number>.</button>
<button data-number>0</button>
<button data-equals class="span-two">=</button>
</div>
</body>
</html>
I think I'm just missing a step that properly integrates the keyboard with corresponding buttons on screen.
I made a basic calculator. Works just fine, except the weirdest thing happens: When I hit enter, AFTER using the buttons on the screen, the display goes blank. But if I use the keyboard FIRST to get an answer, then click the buttons to get another answer, display is fine until I try to use the keyboard again. After some messing around I found that, for some reason, I have to click my screen once, anywhere not on the calculator, before pressing enter works. Otherwise, the display doesn't show.
So it appears to me that im somehow "disconnecting" (for lack of a better term) the display between the keyboard and the on-screen buttons, which causes my display to blank, and I have to "reconnect" it by clicking on the screen outside the calculator in order for hitting enter to not blank.
Any insight would be greatly appreciated, language is javascript. Code has been provided after requested!
When you click on an button, it gets the focus. The default action of the enter key when a button is focused is to click on that button again, so the enter key is repeating whatever you last clicked on, before it performs the action you defined in the document.onkeyup
function.
The solution is to prevent the default action. This default happens in the keydown
event, so you need to add an event listener for that event that calls e.preventDefault()
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 1
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-delete]')
const allClearButton = document.querySelector('[data-all-clear]')
const previousOperandTextElement = document.querySelector('[data-previous-operand]')
const currentOperandTextElement = document.querySelector('[data-current-operand]')
const calculator = new Calculator(previousOperandTextElement, currentOperandTextElement)
numberButtons.forEach(button => {
button.addEventListener('click', () => {
calculator.appendNumber(button.innerText)
calculator.updateDisplay()
})
})
operationButtons.forEach(button => {
button.addEventListener('click', () => {
calculator.chooseOperation(button.innerText)
calculator.updateDisplay()
})
})
equalsButton.addEventListener('click', button => {
calculator.compute()
calculator.updateDisplay()
})
allClearButton.addEventListener('click', button => {
calculator.clear()
calculator.updateDisplay()
})
deleteButton.addEventListener('click', button => {
calculator.delete()
calculator.updateDisplay()
})
document.addEventListener("keydown", e => e.preventDefault());
document.onkeyup = e => {
if (e.key == "1") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "2") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "3") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "4") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "5") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "6") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "7") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "8") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "9") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "0") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == ".") {
calculator.appendNumber(e.key)
calculator.updateDisplay()
} else if (e.key == "+" || e.key == "-" || e.key == "*" || e.key == "/") {
if (e.key == "/") {
let conversion = e.key;
conversion = "÷";
calculator.chooseOperation(conversion)
calculator.updateDisplay()
} else {
calculator.chooseOperation(e.key)
calculator.updateDisplay()
}
} else if (e.key == "Enter") {
equalsButton.click()
} else if (e.key == "Backspace") {
calculator.delete()
calculator.updateDisplay()
}
}
*,
*::before,
*::after {
box-sizing: border-box;
font-family: Gotham Rounded, sans-serif;
font-weight: normal;
}
body {
padding: 0;
margin: 0;
background: linear-gradient(to right, #00AAFF, #00FF6C);
}
.calculator-grid {
display: grid;
justify-content: center;
align-content: center;
min-height: 100vh;
grid-template-columns: repeat(4, 100px);
grid-template-rows: minmax(120px, auto) repeat(5, 100px);
}
.calculator-grid>button {
cursor: pointer;
font-size: 2rem;
border: 2px solid black;
outline: none;
background-color: rgba(255, 255, 255, .75)
}
.calculator-grid>button:hover {
background-color: rgba(255, 255, 255, .9);
}
.span-two {
grid-column: span 2;
}
.output {
grid-column: 1/-1;
background-color: rgba(0, 0, 0, .75);
display: flex;
align-items: flex-end;
justify-content: space-around;
flex-direction: column;
padding: 10px;
word-wrap: break-word;
word-break: break-all;
}
.output .previous-operand {
color: rgba(255, 255, 255, .75);
font-size: 1.5rem;
}
.output .current-operand {
color: white;
font-size: 2.5rem;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Calculator</title>
<link href="styles.css" rel="stylesheet">
<script src="script.js" defer></script>
</head>
<body>
<div class="calculator-grid">
<div class="output">
<div data-previous-operand class="previous-operand"></div>
<div data-current-operand class="current-operand"></div>
</div>
<button data-all-clear class="span-two">AC</button>
<button data-delete>DEL</button>
<button data-operation>÷</button>
<button data-number>1</button>
<button data-number>2</button>
<button data-number>3</button>
<button data-operation>*</button>
<button data-number>4</button>
<button data-number>5</button>
<button data-number>6</button>
<button data-operation>+</button>
<button data-number>7</button>
<button data-number>8</button>
<button data-number>9</button>
<button data-operation>-</button>
<button data-number>.</button>
<button data-number>0</button>
<button data-equals class="span-two">=</button>
</div>
</body>
</html>
Comments
Post a Comment