Pittyh6
Pittyh6

Reputation: 3

Calculator - click on a number the same number is displayed more than once

I'm doing a calculator project. When I click on a number the same number is displayed more than once (only one click on each number). for example, I click on 4, it displays the number 4 once because it was the first click, then I click on the number 1 then it displays the number 1 twice because it was the second number to be clicked.

The code: https://github.com/pittyh6/calculator enter image description here

 function calc() {
    const calculator = document.querySelector(".calculator");
    // All buttons is inside .calculator__keys.
    const keys = document.querySelector(".calculator__keys");
    const display = document.querySelector(".calculator__display");
    // use an event delegation pattern to listen, since keys are all children of .calculator__keys.
    keys.addEventListener("click", (e) => {
        if (e.target.matches("button")) {
            // use the data-action attribute to determine the type of key that is clicked.
            const key = e.target;
            const action = key.dataset.action;
            // The number of the key that was clicked
            const keyContent = key.textContent;
            // The current displayed number
            const displayedNum = display.textContent;

            if (!action) {
                console.log("number key!");
                if (displayedNum === "0") {
                    display.textContent = keyContent;
                    console.log("key content " + keyContent);
                } else {
                    display.textContent = displayedNum + keyContent;
                    console.log("key content " + keyContent);
                }
            } else if (
                action === "add" ||
                action === "subtract" ||
                action === "multiply" ||
                action === "divide"
            ) {
                console.log("operator key");
                //  add the is-depressed class to the operator key
                key.classList.add("is-depressed");
            } else if (action === "decimal") {
                console.log("decimal key");
                display.textContent = displayedNum + ".";
            } else if (action === "clear") {
                console.log("clear key");
            } else if (action === "calculate") {
                console.log("equal key");
            }
        }
    });
}
    <body>
    <div class="container">
        <div class="calculator">
            <div class="calculator__display">0</div>
            <div class="calculator__keys" onclick="calc()">
                <button class="key--operator" data-action="add">+</button>
                <button class="key--operator" data-action="subtract">-</button>
                <button class="key--operator" data-action="multiply">&times;</button>
                <button class="key--operator" data-action="divide">÷</button>
                <button>7</button>
                <button>8</button>
                <button>9</button>
                <button>4</button>
                <button>5</button>
                <button>6</button>
                <button>1</button>
                <button>2</button>
                <button>3</button>
                <button>0</button>
                <button data-action="decimal">.</button>
                <button data-action="clear">AC</button>
                <button class="key--equal" data-action="calculate">=</button>
            </div>
        </div>
    </div>
</body>

Upvotes: 0

Views: 1002

Answers (2)

Swrena
Swrena

Reputation: 330

You are adding an event listener Every time the buttons are clicked.

the event listener should be outside of function calc(). And remove the onclick since you are adding an event listener and don't need it.

const calculator = document.querySelector(".calculator");
    // All buttons is inside .calculator__keys.
    const keys = document.querySelector(".calculator__keys");
    const display = document.querySelector(".calculator__display");
    // use an event delegation pattern to listen, since keys are all children of .calculator__keys.
    
 keys.addEventListener("click", (e) => {
        if (e.target.matches("button")){
          calc(e); 
        }
  });
    
 function calc(e){
     // use the data-action attribute to determine the type of key that is clicked.
            const key = e.target;
            const action = key.dataset.action;
            // The number of the key that was clicked
            const keyContent = key.textContent;
            // The current displayed number
            const displayedNum = display.textContent;

            if (!action) {
                console.log("number key!");
                if (displayedNum === "0") {
                    display.textContent = keyContent;
                    console.log("key content " + keyContent);
                } else {
                    display.textContent = displayedNum + keyContent;
                    console.log("key content " + keyContent);
                }
            } else if (
                action === "add" ||
                action === "subtract" ||
                action === "multiply" ||
                action === "divide"
            ) {
                console.log("operator key");
                //  add the is-depressed class to the operator key
                key.classList.add("is-depressed");
            } else if (action === "decimal") {
                console.log("decimal key");
                display.textContent = displayedNum + ".";
            } else if (action === "clear") {
                console.log("clear key");
            } else if (action === "calculate") {
                console.log("equal key");
            }
  }
<body>
    <div class="container">
        <div class="calculator">
            <div class="calculator__display">0</div>
            <div class="calculator__keys" onclick="">
                <button class="key--operator" data-action="add">+</button>
                <button class="key--operator" data-action="subtract">-</button>
                <button class="key--operator" data-action="multiply">&times;</button>
                <button class="key--operator" data-action="divide">÷</button>
                <button>7</button>
                <button>8</button>
                <button>9</button>
                <button>4</button>
                <button>5</button>
                <button>6</button>
                <button>1</button>
                <button>2</button>
                <button>3</button>
                <button>0</button>
                <button data-action="decimal">.</button>
                <button data-action="clear">AC</button>
                <button class="key--equal" data-action="calculate">=</button>
            </div>
        </div>
    </div>
</body>

Upvotes: 1

MauriceNino
MauriceNino

Reputation: 6757

Every time you click on one of the buttons, the calc function gets called, which adds an event listener to all the buttons. Therefore, with every click, you have one more listener on the button, thus calling the function multiple times. Choose whether you want to use onclick or an event listener.

One option would be to remove the onclick and move the code out of the function to fix your problem like so:

const calculator = document.querySelector(".calculator");
// All buttons is inside .calculator__keys.
const keys = document.querySelector(".calculator__keys");
const display = document.querySelector(".calculator__display");
// use an event delegation pattern to listen, since keys are all children of .calculator__keys.
keys.addEventListener("click", (e) => {
    if (e.target.matches("button")) {
        // use the data-action attribute to determine the type of key that is clicked.
        const key = e.target;
        const action = key.dataset.action;
        // The number of the key that was clicked
        const keyContent = key.textContent;
        // The current displayed number
        const displayedNum = display.textContent;

        if (!action) {
            console.log("number key!");
            if (displayedNum === "0") {
                display.textContent = keyContent;
                console.log("key content " + keyContent);
            } else {
                display.textContent = displayedNum + keyContent;
                console.log("key content " + keyContent);
            }
        } else if (
            action === "add" ||
            action === "subtract" ||
            action === "multiply" ||
            action === "divide"
        ) {
            console.log("operator key");
            //  add the is-depressed class to the operator key
            key.classList.add("is-depressed");
        } else if (action === "decimal") {
            console.log("decimal key");
            display.textContent = displayedNum + ".";
        } else if (action === "clear") {
            console.log("clear key");
        } else if (action === "calculate") {
            console.log("equal key");
        }
    }
});
  <body>
  <div class="container">
      <div class="calculator">
          <div class="calculator__display">0</div>
          <div class="calculator__keys">
              <button class="key--operator" data-action="add">+</button>
              <button class="key--operator" data-action="subtract">-</button>
              <button class="key--operator" data-action="multiply">&times;</button>
              <button class="key--operator" data-action="divide">÷</button>
              <button>7</button>
              <button>8</button>
              <button>9</button>
              <button>4</button>
              <button>5</button>
              <button>6</button>
              <button>1</button>
              <button>2</button>
              <button>3</button>
              <button>0</button>
              <button data-action="decimal">.</button>
              <button data-action="clear">AC</button>
              <button class="key--equal" data-action="calculate">=</button>
          </div>
      </div>
  </div>
</body>

Upvotes: 2

Related Questions