Home > Back-end >  How can i combine both keyboard and on click combinations?
How can i combine both keyboard and on click combinations?

Time:09-29

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>

  • Related