odin-calculator/script.js

241 lines
6.1 KiB
JavaScript
Raw Normal View History

2023-12-27 13:40:15 -07:00
const mainScreen = document.querySelector(".main-screen");
const topScreen = document.querySelector(".top-screen");
2023-12-27 20:26:04 -07:00
const numButtons = document.querySelectorAll(".num");
const equalButton = document.querySelector(".equal");
const opButtons = document.querySelectorAll(".operator");
const clearButtons = document.querySelectorAll(".clear");
const plusMinus = document.querySelector(".plus-minus");
let inOps = false;
let isEval = false;
2023-12-27 20:26:04 -07:00
numButtons.forEach((button) => {
button.addEventListener("click", displayNum);
});
2023-12-27 20:26:04 -07:00
opButtons.forEach((button) => {
button.addEventListener("click", displayOperator);
});
clearButtons.forEach((button) => {
button.addEventListener("click", clear);
});
equalButton.addEventListener("click", displayEval);
plusMinus.addEventListener("click", changeSign);
2023-12-28 00:20:46 -07:00
window.addEventListener("keydown", handleKeys);
2023-12-27 20:26:04 -07:00
function displayEval() {
let calc = new Calculator;
let result = 0
if (topScreen.textContent === "0" || !inOps) {
result = calc.calculate(mainScreen.textContent);
2023-12-27 20:26:04 -07:00
} else {
topScreen.textContent += mainScreen.textContent;
result = calc.calculate(topScreen.textContent);
}
mainScreen.textContent = result;
inOps = false;
isEval = true;
2023-12-27 20:26:04 -07:00
}
function displayOperator() {
let result = 0
let operator = this.textContent;
if (operator == "-" && (isNaN(mainScreen.textContent) || mainScreen.textContent == "0")) {
changeSign();
return;
}
2023-12-27 20:26:04 -07:00
if (topScreen.textContent == "" || !inOps) {
topScreen.textContent = mainScreen.textContent + " " + this.textContent + " ";
} else {
2023-12-26 21:25:33 -07:00
let calc = new Calculator;
2023-12-27 20:26:04 -07:00
topScreen.textContent += mainScreen.textContent;
result = calc.calculate(topScreen.textContent);
topScreen.textContent = result + " " + this.textContent + " ";
}
mainScreen.textContent = 0;
inOps = true;
isEval = false;
2023-12-27 20:26:04 -07:00
}
function displayNum() {
if (mainScreen.textContent == "0" || isEval) {
2023-12-27 20:26:04 -07:00
mainScreen.textContent = this.textContent;
2023-12-28 15:07:12 -07:00
} else if (mainScreen.textContent.length < 8) {
2023-12-27 20:26:04 -07:00
mainScreen.textContent += this.textContent;
}
if (isEval) {
topScreen.textContent = "";
}
isEval = false;
2023-12-27 20:26:04 -07:00
}
2023-12-27 20:26:04 -07:00
function clear() {
if (this.classList.contains("all")) {
2023-12-27 13:40:15 -07:00
mainScreen.textContent = "0";
2023-12-27 14:14:07 -07:00
topScreen.textContent = "";
} else if (this.classList.contains("entry") && mainScreen.textContent !== "0") {
if (/^[0-9.]+$/.test(mainScreen.textContent)) {
mainScreen.textContent = mainScreen.textContent.slice(0, -1);
} else {
mainScreen.textContent = "";
}
2023-12-27 13:40:15 -07:00
if (mainScreen.textContent === "") {
mainScreen.textContent = "0"
}
}
2023-12-26 21:25:33 -07:00
}
function changeSign() {
2023-12-28 07:34:04 -07:00
let num = mainScreen.textContent;
if (num === "0") {
mainScreen.textContent = "-";
2023-12-28 07:34:04 -07:00
} else if (num === "-") {
mainScreen.textContent = "0";
} else if (num.startsWith("-")) {
mainScreen.textContent = num.substring(1);
} else {
mainScreen.textContent = `-${num}`;
}
2023-12-28 07:34:04 -07:00
}
2023-12-27 01:51:17 -07:00
function addDecimals(a, b) {
a = String(a);
b = String(b);
const adec = (a.split(".")[1] || "").length;
const bdec = (b.split(".")[1] || "").length;
const maxDec = Math.max(adec, bdec);
2023-12-27 01:51:17 -07:00
let divdec = "1";
divdec = divdec.padEnd(maxDec, "0");
return ((+a * divdec + +b * divdec) / divdec).toFixed(maxDec);
}
function multiplyDecimals(a, b) {
a = String(a);
b = String(b);
const adec = (a.split(".")[1] || "").length;
const bdec = (b.split(".")[1] || "").length;
const totalDec = adec + bdec;
return (a * b).toFixed(totalDec)
}
function divideDecimals(a, b) {
a = String(a);
b = String(b);
const adec = (a.split(".")[1] || "").length;
const bdec = (b.split(".")[1] || "").length;
const maxDec = Math.max(adec, bdec);
const divisor = Math.pow(10, maxDec);
return(a * divisor) / (b * divisor);
2023-12-27 01:51:17 -07:00
}
2023-12-26 21:25:33 -07:00
function Calculator(str) {
isEval = true;
2023-12-26 21:25:33 -07:00
2023-12-26 17:15:28 -07:00
this.methods = {
2023-12-27 01:51:17 -07:00
"-": (a, b) => addDecimals(a, -b),
"+": (a, b) => addDecimals(a, b),
"/": (a, b) => divideDecimals(a, b),
"*": (a, b) => multiplyDecimals(a, b)
2023-12-26 17:15:28 -07:00
};
this.calculate = function(str) {
let parts = str.split(" ");
a = +parts[0];
op = parts[1];
b = +parts[2];
2023-12-27 21:07:13 -07:00
if ((a || a == "0") && !op && !b) {
2023-12-28 16:07:03 -07:00
return formatResult(a);
}
2023-12-26 17:15:28 -07:00
if (isNaN(a) || isNaN(b)) {
return NaN;
}
if (!this.methods[op]) {
return "Operation not supported."
}
2023-12-28 15:07:12 -07:00
let result = this.methods[op](a, b);
return formatResult(result);
2023-12-26 17:15:28 -07:00
};
2023-12-28 00:20:46 -07:00
}
2023-12-28 15:07:12 -07:00
function formatResult(result) {
const resultStr = result.toString();
const maxLength = 9;
if (resultStr.length > maxLength) {
expoResult = parseFloat(result).toExponential(maxLength - 6);
return expoResult;
}
return result;
}
2023-12-28 00:20:46 -07:00
function handleKeys(e) {
const operators = {
"+": "plus",
"-": "minus",
"*": "multiply",
"/": "divide"
};
2023-12-28 09:44:07 -07:00
let button;
2023-12-28 00:20:46 -07:00
if (e.key >= 0 && e.key <= 9) {
2023-12-28 09:44:07 -07:00
button = document.querySelector(`#num${e.key}`);
2023-12-28 00:20:46 -07:00
} else if (e.key === ".") {
2023-12-28 09:44:07 -07:00
button = document.querySelector("#dec");
2023-12-28 00:20:46 -07:00
} else if (e.key === "Backspace" || e.key === "Delete") {
button = document.querySelector(".entry");
} else if (e.key === "c" || e.key === "C" || e.key === "Escape") {
2023-12-28 09:44:07 -07:00
button = document.querySelector(".all");
2023-12-28 00:20:46 -07:00
} else if (operators.hasOwnProperty(e.key)) {
e.preventDefault();
2023-12-28 09:44:07 -07:00
button = document.querySelector(`#${operators[e.key]}`);
2023-12-28 00:20:46 -07:00
} else if (e.key === "=" || e.key === "Enter") {
e.preventDefault();
2023-12-28 09:44:07 -07:00
button = document.querySelector(".equal");
2023-12-28 07:34:04 -07:00
} else if (e.key === "_") {
2023-12-28 09:44:07 -07:00
button = document.querySelector(".plus-minus");
}
if (button) {
button.classList.add("active");
window.addEventListener("keyup", () => {
button.classList.remove("active")
});
button.click();
2023-12-28 00:20:46 -07:00
}
}