简体   繁体   中英

Pure Javascript: What is the best way to click a button in the group of buttons in a calculator?

I have this code that I built in HTML/CSS that's based on Mac/Apple calculator. The way it's displayed is that buttons are grouped in 5 rows using flexbox.

Here's my code from this codepen :

<div class="wrapper">
  <div class="calheader">
      <h2>Simple Calculator</h2>
    </div>
  <div class="calculatorbox">
    <div class="calwindow">
      <!-- ENTRY BOX -->
     <div class="entry">
        <p id="answer"></p>
      </div>
      <div class="entryhistory">
        <p id="history"></p>
      </div>
    </div>
    <!-- BUTTONS \\-->
    <div class="calbuttons">
      <div class="row">
        <button id="clear" class="key topcolor" value="clear">C</button>
        <button class="key topcolor" value="plusminus"><sup>+</sup>/<sub>−</sub></button>
        <button class="key topcolor" value="%">%</button>
        <button id="divide" class="key orange" value="/">÷</button>
      </div>
      <div class="row">
        <button id="seven" class="key" value="7">7</button>
        <button id="eight" class="key" value="8">8</button>
        <button id="nine" class="key" value="9">9</button>
        <button id="multiply" class="key orange" value="*">×</button>
      </div>
      <div class="row">
        <button id="four" class="key" value="4">4</button>
        <button id="five" class="key" value="5">5</button>
        <button id="six" class="key" value="6">6</button>
        <button id="subtract" class="key orange" value="-">−</button>
      </div>
      <div class="row">
        <button id="one" class="key" value="1">1</button>
        <button id="two" class="key" value="2">2</button>
        <button id="three" class="key" value="3">3</button>
        <button id="add" class="key orange" value="+">+</button>
      </div>
      <div class="row">
        <button id="zero" class="key btnspan" value="0">0</button>
        <button id="decimal" class="key" value=".">.</button>
        <button id="equals" class="key orange" value="=">=</button>
      </div>
    </div>
  </div>
</div>

Now, I'm trying to figure out how to select the button so that I can use addEventListener to each button.

Other pure javascript tutorial I have checked out only has this display:

<div class="calculator-keys">
    
    <button type="button" class="operator" value="+">+</button>
    <button type="button" class="operator" value="-">-</button>
    <button type="button" class="operator" value="*">&times;</button>
    <button type="button" class="operator" value="/">&divide;</button>

    <button type="button" value="7">7</button>
    <button type="button" value="8">8</button>
    <button type="button" value="9">9</button>


    <button type="button" value="4">4</button>
    <button type="button" value="5">5</button>
    <button type="button" value="6">6</button>


    <button type="button" value="1">1</button>
    <button type="button" value="2">2</button>
    <button type="button" value="3">3</button>


    <button type="button" value="0">0</button>
    <button type="button" class="decimal" value=".">.</button>
    <button type="button" class="all-clear" value="all-clear">AC</button>

    <button type="button" class="equal-sign operator" value="=">=</button>

  </div>

so that he will be able to use this code:

const keys = document.querySelector('.calculator-keys');

keys.addEventListener('click', (event) => {
  const { target } = event;
  console.log('digit', target.value);
});

What I understand is that this tutorial I've checked out use querySelector to select all the children within the class calculator-keys .

In my case, I was able to make it work for only the first row. However, if I use querySelectorAll , do I need to use .map() , .forEach() , or something else in order to use addEventListener on each button?

querySelector return only one element so you need to use querySelectorAll you need to select all elements with class key and then add event listener for each key

 const keys = document.querySelectorAll('.key'); keys.forEach(item => { item.addEventListener('click', (event) => { const { target } = event; console.log('digit', target.value); }); });
 <div class="wrapper"> <div class="calheader"> <h2>Simple Calculator</h2> </div> <div class="calculatorbox"> <div class="calwindow"> <.-- ENTRY BOX --> <div class="entry"> <p id="answer"></p> </div> <div class="entryhistory"> <p id="history"></p> </div> </div> <.-- BUTTONS \\--> <div class="calbuttons"> <div class="row"> <button id="clear" class="key topcolor" value="clear">C</button> <button class="key topcolor" value="plusminus"><sup>+</sup>/<sub>−</sub></button> <button class="key topcolor" value="%">%</button> <button id="divide" class="key orange" value="/">÷</button> </div> <div class="row"> <button id="seven" class="key" value="7">7</button> <button id="eight" class="key" value="8">8</button> <button id="nine" class="key" value="9">9</button> <button id="multiply" class="key orange" value="*">×</button> </div> <div class="row"> <button id="four" class="key" value="4">4</button> <button id="five" class="key" value="5">5</button> <button id="six" class="key" value="6">6</button> <button id="subtract" class="key orange" value="-">−</button> </div> <div class="row"> <button id="one" class="key" value="1">1</button> <button id="two" class="key" value="2">2</button> <button id="three" class="key" value="3">3</button> <button id="add" class="key orange" value="+">+</button> </div> <div class="row"> <button id="zero" class="key btnspan" value="0">0</button> <button id="decimal" class="key" value=".">.</button> <button id="equals" class="key orange" value="=">=</button> </div> </div> </div> </div>

Dom event deligation refers to handling bubbling events from many elements. It can keep the code simpler, especially when adding or removing elements, and saves some memory.

Some code examples of event delegation:

  1. JavaScript Event Delegation

  2. DOM Events

If you are using Javascript and you have a list of buttons with class ' key ', you can use this code to add an EventListener to each button.

let buttons = document.getElementsByClassName('key');
    for(let i = 0; i<buttons.length; i++){
       buttons[i].addEventListener('click', () => {
          /*add your code here*/
       });
    }

querySelectoAll returns a NodeList, you can create an array from buttons, iterate and assign an eventListener

 let buttons = document.querySelectorAll('.btn'); let arrButtons = Array.from(buttons); console.log(arrButtons) for(button of arrButtons){ button.addEventListener('click', () => { console.log('event'); }) }
 <button class="btn">Go!</button> <button class="btn">Go!</button> <button class="btn">Go!</button> <button class="btn">Go!</button>

The best way is to use event delegation . This way you don't have to attach event listener on each button, but only on their parent container.

 const calculator = document.querySelector(".calculator-keys"); // only attach click event on the container calculator.addEventListener("click", (event) => { // ignore clicks from non-button element if (event.target.nodeName;== "BUTTON") return. console.log(event.target;value); });
 <div class="calculator-keys"> <button type="button" class="operator" value="+">+</button> <button type="button" class="operator" value="-">-</button> <button type="button" class="operator" value="*">&times;</button> <button type="button" class="operator" value="/">&divide;</button> <button type="button" value="7">7</button> <button type="button" value="8">8</button> <button type="button" value="9">9</button> <button type="button" value="4">4</button> <button type="button" value="5">5</button> <button type="button" value="6">6</button> <button type="button" value="1">1</button> <button type="button" value="2">2</button> <button type="button" value="3">3</button> <button type="button" value="0">0</button> <button type="button" class="decimal" value=".">.</button> <button type="button" class="all-clear" value="all-clear">AC</button> <button type="button" class="equal-sign operator" value="=">=</button> </div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM