let operator = "";
let currentValue = "";
let previousValue = "";
document.addEventListener("DOMContentLoaded", () => {
let clear = document.querySelector("#clear-btn");
let equal = document.querySelector(".equal");
let decimal = document.querySelector(".decimal");
let numbers = document.querySelectorAll(".number");
let operators = document.querySelectorAll(".operator");
let previousScreen = document.querySelector(".previous");
let currentScreen = document.querySelector(".current");
numbers.forEach((number) => {
number.addEventListener("click", (e) => {
handleNumber(e.target.textContent);
currentScreen.textContent = currentValue;
});
});
operators.forEach((op) => {
op.addEventListener("click", (e) => {
handleOperator(e.target.textContent);
previousScreen.textContent = previousValue " " operator;
currentScreen.textContent = currentValue;
});
});
clear.addEventListener("click", () => {
operator = "";
currentValue = "";
previousValue = "";
previousScreen.textContent = currentValue;
currentScreen.textContent = currentValue;
});
equal.addEventListener("click", () => {
if (currentValue != "" && previousValue != "") {
calculate();
previousScreen.textContent = "";
if (previousValue.length <= 5) {
currentScreen.textContent = previousValue;
} else {
currentScreen.textContent = previousValue.slice(0, 5) "...";
}
}
});
decimal.addEventListener("click", () => {
addDecimal();
});
});
function handleNumber(num) {
if (currentValue.length <= 5) {
currentValue = num;
}
}
function handleOperator(op) {
operator = op;
previousValue = currentValue;
currentValue = "";
}
function calculate() {
previousValue = Number(previousValue);
currentValue = Number(currentValue);
if (operator === " ") {
previousValue = currentValue;
} else if (operator === "-") {
previousValue -= currentValue;
} else if (operator === "x") {
previousValue *= currentValue;
} else if (operator === "/") {
previousValue /= currentValue;
}
previousValue = roundNum(previousValue);
previousValue = previousValue.toString();
currentValue = previousValue.toString();
}
function roundNum(num) {
return Math.round(num * 1000) / 1000;
}
function addDecimal() {
if (!currentValue.includes(".")) {
currentValue = ".";
}
}
window.onkeydown = function(e) {
let x = e.key;
let choice;
switch (x) {
case "1":
choice = document.querySelector(".one");
choice.click();
break;
case "2":
choice = document.querySelector(".two");
choice.click();
break;
case "3":
choice = document.querySelector(".three");
choice.click();
break;
case "4":
choice = document.querySelector(".four");
choice.click();
break;
case "5":
choice = document.querySelector(".five");
choice.click();
break;
case "6":
choice = document.querySelector(".six");
choice.click();
break;
case "7":
choice = document.querySelector(".seven");
choice.click();
break;
case "8":
choice = document.querySelector(".eight");
choice.click();
break;
case "9":
choice = document.querySelector(".nine");
choice.click();
break;
case "0":
choice = document.querySelector(".zero");
choice.click();
break;
case "/":
choice = document.querySelector(".division");
choice.click();
break;
case "*":
choice = document.querySelector(".multiply");
choice.click();
break;
case "-":
choice = document.querySelector(".minus");
choice.click();
break;
case " ":
choice = document.querySelector(".plus");
choice.click();
break;
case ".":
choice = document.querySelector(".decimal");
choice.click();
break;
case "Enter":
choice = document.querySelector(".equal");
choice.click();
break;
case "Backspace":
choice = document.querySelector("#clear-btn");
choice.click();
break;
}
};
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.btn {
height: 75px;
width: 75px;
margin: 15px;
font-size: 40px;
}
.number {
border: 1px solid yellowgreen;
border-radius: 10px;
}
.number:hover {
background-color: palegreen;
}
.operator {
border: 1px solid steelblue;
border-radius: 10px;
}
.operator:hover {
background-color: paleturquoise;
}
.decimal {
border: 1px solid gold;
border-radius: 10px;
}
.decimal:hover {
background-color: palegoldenrod;
}
.equal {
border: 1px solid pink;
border-radius: 10px;
}
.equal:hover {
background-color: plum;
}
#clear-btn {
border: 1px solid violet;
border-radius: 10px;
}
#clear-btn:hover {
background-color: palevioletred;
}
.first-row {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
}
#screen {
width: 300px;
border: 1px solid salmon;
height: 75px;
margin: 15px;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-end;
}
.previous {
font-size: 20px;
}
.current {
font-size: 30px;
}
<!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>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI N" crossorigin="anonymous" />
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Calculator</h1>
<div >
<div >
<div id="screen">
<div ></div>
<div ></div>
</div>
<button id="clear-btn" >C</button>
</div>
<div >
<button >7</button>
<button >8</button>
<button >9</button>
<button >/</button>
</div>
<div >
<button >4</button>
<button >5</button>
<button >6</button>
<button >x</button>
</div>
<div >
<button >1</button>
<button >2</button>
<button >3</button>
<button >-</button>
</div>
<div >
<button >.</button>
<button >0</button>
<button >=</button>
<button > </button>
</div>
</div>
</body>
</html>
I'm not sure if my code is best practice but when trying to implement both on click and keydown functions my application does not work. For example, type 5*5
and press Enter (the answer shows). Then proceed to CLICK the C
to clear and type 5*5
and press Enter again. This time the answer will not be shown. I'm not sure what the error is. Is there a better way to implement both click and keydown functions?
CodePudding user response:
Your general approach is fine. The problem is that the Enter key has a default action of clicking on the active button. Since the last button you clicked on was C
, Enter is clicking on this again, which is clearing the result after it's displayed.
Call e.preventDefault()
in the keydown listener to stop this.
let operator = "";
let currentValue = "";
let previousValue = "";
document.addEventListener("DOMContentLoaded", () => {
let clear = document.querySelector("#clear-btn");
let equal = document.querySelector(".equal");
let decimal = document.querySelector(".decimal");
let numbers = document.querySelectorAll(".number");
let operators = document.querySelectorAll(".operator");
let previousScreen = document.querySelector(".previous");
let currentScreen = document.querySelector(".current");
numbers.forEach((number) => {
number.addEventListener("click", (e) => {
handleNumber(e.target.textContent);
currentScreen.textContent = currentValue;
});
});
operators.forEach((op) => {
op.addEventListener("click", (e) => {
handleOperator(e.target.textContent);
previousScreen.textContent = previousValue " " operator;
currentScreen.textContent = currentValue;
});
});
clear.addEventListener("click", () => {
operator = "";
currentValue = "";
previousValue = "";
previousScreen.textContent = currentValue;
currentScreen.textContent = currentValue;
});
equal.addEventListener("click", () => {
if (currentValue != "" && previousValue != "") {
calculate();
previousScreen.textContent = "";
if (previousValue.length <= 5) {
currentScreen.textContent = previousValue;
} else {
currentScreen.textContent = previousValue.slice(0, 5) "...";
}
}
});
decimal.addEventListener("click", () => {
addDecimal();
});
});
function handleNumber(num) {
if (currentValue.length <= 5) {
currentValue = num;
}
}
function handleOperator(op) {
operator = op;
previousValue = currentValue;
currentValue = "";
}
function calculate() {
previousValue = Number(previousValue);
currentValue = Number(currentValue);
if (operator === " ") {
previousValue = currentValue;
} else if (operator === "-") {
previousValue -= currentValue;
} else if (operator === "x") {
previousValue *= currentValue;
} else if (operator === "/") {
previousValue /= currentValue;
}
previousValue = roundNum(previousValue);
previousValue = previousValue.toString();
currentValue = previousValue.toString();
}
function roundNum(num) {
return Math.round(num * 1000) / 1000;
}
function addDecimal() {
if (!currentValue.includes(".")) {
currentValue = ".";
}
}
window.onkeydown = function(e) {
e.preventDefault();
let x = e.key;
let choice;
switch (x) {
case "1":
choice = document.querySelector(".one");
choice.click();
break;
case "2":
choice = document.querySelector(".two");
choice.click();
break;
case "3":
choice = document.querySelector(".three");
choice.click();
break;
case "4":
choice = document.querySelector(".four");
choice.click();
break;
case "5":
choice = document.querySelector(".five");
choice.click();
break;
case "6":
choice = document.querySelector(".six");
choice.click();
break;
case "7":
choice = document.querySelector(".seven");
choice.click();
break;
case "8":
choice = document.querySelector(".eight");
choice.click();
break;
case "9":
choice = document.querySelector(".nine");
choice.click();
break;
case "0":
choice = document.querySelector(".zero");
choice.click();
break;
case "/":
choice = document.querySelector(".division");
choice.click();
break;
case "*":
choice = document.querySelector(".multiply");
choice.click();
break;
case "-":
choice = document.querySelector(".minus");
choice.click();
break;
case " ":
choice = document.querySelector(".plus");
choice.click();
break;
case ".":
choice = document.querySelector(".decimal");
choice.click();
break;
case "Enter":
choice = document.querySelector(".equal");
choice.click();
break;
case "Backspace":
choice = document.querySelector("#clear-btn");
choice.click();
break;
}
};
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.btn {
height: 75px;
width: 75px;
margin: 15px;
font-size: 40px;
}
.number {
border: 1px solid yellowgreen;
border-radius: 10px;
}
.number:hover {
background-color: palegreen;
}
.operator {
border: 1px solid steelblue;
border-radius: 10px;
}
.operator:hover {
background-color: paleturquoise;
}
.decimal {
border: 1px solid gold;
border-radius: 10px;
}
.decimal:hover {
background-color: palegoldenrod;
}
.equal {
border: 1px solid pink;
border-radius: 10px;
}
.equal:hover {
background-color: plum;
}
#clear-btn {
border: 1px solid violet;
border-radius: 10px;
}
#clear-btn:hover {
background-color: palevioletred;
}
.first-row {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
}
#screen {
width: 300px;
border: 1px solid salmon;
height: 75px;
margin: 15px;
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: flex-end;
}
.previous {
font-size: 20px;
}
.current {
font-size: 30px;
}
<!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>Document</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI N" crossorigin="anonymous" />
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Calculator</h1>
<div >
<div >
<div id="screen">
<div ></div>
<div ></div>
</div>
<button id="clear-btn" >C</button>
</div>
<div >
<button >7</button>
<button >8</button>
<button >9</button>
<button >/</button>
</div>
<div >
<button >4</button>
<button >5</button>
<button >6</button>
<button >x</button>
</div>
<div >
<button >1</button>
<button >2</button>
<button >3</button>
<button >-</button>
</div>
<div >
<button >.</button>
<button >0</button>
<button >=</button>
<button > </button>
</div>
</div>
</body>
</html>