What is the reason behind not being able to utilize addEventListener on a variable that has been selected through DOM's getElementsByClassName method?

btn = document.getElementsByClassName('btn');
value = document.getElementById('value');

let counter = 0;

btn[2].addEventListener('click', function() {
  if (btn[2].classList.contains('decrease')) counter -= 1;
  if (btn[2].classList.contains('reset')) counter = 0;
  if (btn[2].classList.contains('increase')) counter += 1;
  value.innerText = counter;
});
/*
=============== 
Fonts
===============
*/

@import url("https://fonts.googleapis.com/css?family=Open+Sans|Roboto:400,700&display=swap");

/*
=============== 
Variables
===============
*/

:root {
  /* dark shades of primary color*/
... (variables continue)
...
<!DOCTYPE html>
<html lang="en">

<head>
 ...(head section continues)...
 ...</head>

<body>
...(body section continues)...
... </body>

</html>

It seems that the issue lies in the JavaScript code snippet. When clicking on the increase button with index 2, the value doesn't increase as expected.

btn = document.getElementsByClassName('btn'); 

btn[2].addEventListener('click', function() {
  if (btn[2].classList.contains('decrease')) counter -= 1;
  if (btn[2].classList.contains('reset')) counter = 0;
  if (btn[2].classList.contains('decrease')) counter += 1;
  value.innerText = counter;
});

Answer №1

Iterate through the list of nodes and attach an event listener to all buttons. Determine which button triggered the event by examining the classList of the event target.

btn = document.getElementsByClassName('btn');
value = document.getElementById('value');

let counter = 0;

Array.from(btn).forEach((e) => {e.addEventListener('click', function(e) {
    if (e.target.classList.contains('decrease')) counter -= 1;
    if (e.target.classList.contains('reset')) counter = 0;
    if (e.target.classList.contains('increase')) counter += 1;
    value.innerText = counter;
  })
});
/* CSS Styles */ 
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Counter</title>

  <!-- styles -->
  <link rel="stylesheet" href="styles.css" />
</head>

<body>
  <main>
    <div class="container">
      <h1>
        counter
      </h1>
      <span id="value">0</span>
      <div class="button-container">
        <button class="btn decrease">decrease</button>
        <button class="btn reset">reset</button>
        <button class="btn increase">increase</button>
      </div>
    </div>
  </main>
  <!-- javascript -->
  <script src="app.js"></script>
</body>

</html>

Answer №2

Firstly, there is a typo in the third if statement that needs correction:

if (btn[2].classList.contains('increase')) counter += 1;

It should be increase instead of decrease.

Secondly, a more versatile approach would be:

let onClickUpdate = function() {
  if (this.classList.contains('decrease')) counter -= 1;
  if (this.classList.contains('reset')) counter = 0;
  if (this.classList.contains('increase')) counter += 1;
  value.innerText = counter;
};

//btn[0].addEventListener('click', onClickUpdate);
//btn[1].addEventListener('click', onClickUpdate);
btn[2].addEventListener('click', onClickUpdate);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Combine the points of individual letters in Scrabble using jQuery

Hello, I'm currently working on creating a Scrabble game. My goal is to assign a value to each letter and then calculate the sum of these values when the input box changes. After some research, I was able to find information on how to add numbers on ...

utilizing a pair of API requests within a personalized Alexa skill

I posted a question about integrating Alexa with the Steam custom skill API here, but I realize it might be too detailed for some to read through. In essence, my main question is: Can you make two separate API calls within the same block of JS code while ...

When it comes to using jQuery, I find that it only functions properly when I manually input the code into the Google Chrome console. Otherwise

Below is the HTML snippet: <textarea cols="5" disabled id="textareRSAKeypair"> @Model["keypair"] </textarea> <a href="#" class="btn btn-primary" id="downloadKeypair">Download Key</a> Here is the jQuery code: <script src="ht ...

User-generated JSON Object with Date Information

I have created an API using Node.js/Express that receives input from a form including a date option in the request body. Currently, I am sending dates in the format YYYY-mm-dd, and I have also attempted using dd/mm/YYYY. However, when testing in Postman, ...

Troubleshooting a scenario where making edits to a mongoDB item does not result in any updates

I am struggling with a problem in my nodeJS application involving updating items in a mongoDB database. I have successfully implemented features to add and remove notes, but when attempting to update a note, the changes do not reflect in the database. Desp ...

Switching the keyboard language on the client side of programming languages

I'm interested in altering the keyboard language when an input element changes. Is it possible to modify the keyboard language using client-side programming languages? And specifically, can JavaScript be used to change the keyboard language? ...

Sometimes in VueJs, the global data that has been loaded may become null

Hello, I am currently exploring VueJs and looking for a way to load data once and share it across all Vue components. I've encountered an issue where global variables sometimes become null unexpectedly. In my main.js file, I have defined three global ...

Copy the contents of matrixA into matrixB and append a new element to each array within matrixB

I want to copy the values from matrixA into matrixB and then add a new element to each array in matrixB. let number = 100; matrixA = [ [1, 2], [3, 4] ]; matrixB = [ [1, 2, 100], [3, 4, 100] ]; Currently, my code looks like this: for (let ...

Traverse through an array of objects with unspecified length and undefined key names

Consider the following object arrays: 1. [{id:'1', code:'somecode', desc:'this is the description'}, {...}, {...}] 2. [{fname:'name', lname:'last name', address:'my address', email:'<a h ...

Watch the Newest Vimeo Showcase Reel

I have a new project where my client is requesting to display the latest video from a specific Vimeo Portfolio. I already have a script that can fetch the latest video from the entire account using JavaScript as shown below: http://codepen.io/buschschwick ...

I am experiencing an issue with my Angular directive where the button click does not

Check out this page for guidance on adding a div with a button click in AngularJS: How to add div with a button click in angularJs I attempted to create an angular directive that should add a div to my HTML page when a button is clicked. However, upon cli ...

What can be done to ensure that the a href tag is functioning as clickable?

Having an issue with my HTML and CSS code for a notification dropdown box. I am unable to click the tag, even after attempting to use JavaScript. Can't seem to figure out what's causing this problem. Any advice on how to make the tag clickable? ...

Issue with Material UI React: Navbar does not properly align the box to the right side

https://i.sstatic.net/CHSwp.png I'm facing an issue with my navbar that is supposed to align all the page options to the right. Despite using a flexbox layout and trying different alignment properties like alignSelf: end, the text only moves slightly ...

Creating a JavaScript and C# popup for deleting records in asp.net

I'm struggling a bit with understanding how server-side deletion works. I know how to use MessageBox, but it's not the best approach. I've been advised to use a popup on the server side. What I'm trying to achieve is that when you clic ...

Cypress and VueJS: How to target elements that are dynamically generated following a specific user interaction

I am currently testing a new feature where a button will only appear for the user to click after they have completed another action. Before proceeding with the action, I am verifying if the button exists: cy.get('span') .contains('Selec ...

Issue with Ionic Grid: Row not occupying entire width of the container

Currently, I am working on creating a straightforward grid consisting of one row and seven columns. Each column holds a div with a single letter of text inside. My intention is for these columns to evenly space out across the page by default, but unfortu ...

What causes Vue to only update once when there are two closely timed mutations to reactive data?

Can you take a look at this simple example? export default { data() { return { name: "Amy", age: 18, }; }, computed: { combinedDataForWatching() { return { name: this.name, age: this.age, ...

How come my jQuery isn't updating the class of a specific element?

I apologize if this question seems too specific to my own project, but I am facing a dilemma. I am attempting to change the color of the title of the user's current page to orange when hovering over the page name in the navigation menu. In simpler ter ...

Switch up div content - advertisements at the top or bottom

An issue has arisen where the ads on a website are currently being displayed at the bottom of the source code, but they should actually be visible at the top. Here is the ad placeholder code: <div id="300_250_placeholder"></div> And here is ...

Error in ThreeJS: The constructor THREE.FaceNormalsHelper is not defined

I am currently studying a course on three.js and encountered an issue in Chrome version 79 while progressing through the material: "THREE.FaceNormalsHelper is not a constructor". The line causing trouble is as follows: normals = new THREE.FaceNormalsH ...