How can I repeatedly trigger an eventListener in JavaScript?

I'm currently facing an issue with calling the event listener for all 4 progress bars on my page. The problem is that it's only working on the first progress bar. I cloned the div with the id of 'mycontainer' using a for loop, but the event listener seems to only recognize the first progress bar and not the rest. Here is the relevant code snippet:

</head>
  <body >
   <div id="headdiv">
       <div id="mycontainer" style="width: auto;float: left;margin-left: 2%;">
    <input
      id="threshold"
      placeholder="threshold value"
      type="text"
      name="thresholdd"
      style="width: 120px; margin-top: 30px;margin-left: 0%; padding: 10px;" />
    <input
      id="live"
      placeholder="live value"
      type="text"
      name="livee"
      style="width: 120px; margin-bottom: 20px;padding: 10px;"   />

    <div id="progress-container" class="progress-container">
      <div id="progress-bar" class="progress-bar"></div>
    </div>
</div>
</div>
  </body>
  <script>
    const progressBar = window.document.getElementById("progress-bar");
    const progressContainer = window.document.getElementById( "progress-container");
    const threshold = window.document.getElementById("threshold"); 
    let thresholdValue, value;
    threshold.addEventListener("change", e => { thresholdValue = e.target.value;});
    live.addEventListener("change", e => {
      value = e.target.value;
      let percentValue = Math.floor((value / (2 * thresholdValue)) * 100);
      let percentMargin = Math.floor((25 * value) / 100);
      console.log(percentValue, percentMargin);
      if ( value < 100) {
        progressBar.style.height = `calc(${value}% - ${percentMargin}px)`;
      } else if (value => 100) {
        progressBar.style.height = `calc(100% - 25px)`;
      } else {
        progressBar.style.height = `0px`;
      }
      if (percentValue < 50) {
        progressBar.style.backgroundColor = "red";
        progressContainer.style.borderColor = "red";
      } else {
        progressBar.style.backgroundColor = "green";
        progressContainer.style.borderColor = "green";
      }
    });  
          for(var i=0;i<4;i++)
          {
 var headdiv=document.getElementById('headdiv');
var elem = document.querySelector('#mycontainer');
var clone = elem.cloneNode(true);
clone.id = 'mycontainer'+i;
headdiv.appendChild(clone);
}
  </script>
</html>

Answer №1

Modify id to class name

Each element should have a unique id.

When using document.getElementById, only the first matched element will be returned.

Therefore, it is recommended to utilize class instead of id.

With document.getElementsByClassName, all elements with matching class names will be retrieved.

Additionally, event listeners must be bound to the document and then verified for the element.

Considering that your elements are dynamically generated, addEventListener can only attach events to elements existing in the DOM tree.

For instance:

const progressBar = window.document.getElementById("progress-bar");
const progressContainer = window.document.getElementById("progress-container");
const threshold = window.document.getElementsByClassName("threshold");
let thresholdValue, value;
const live = document.getElementsByClassName("live");

document.addEventListener("change", e => {
  if (e.target.className.indexOf('threshold') > -1) {
    thresholdValue = e.target.value;
  } else if (e.target.className.indexOf('live') > -1) {
    value = e.target.value;
    let percentValue = Math.floor((value / (2 * thresholdValue)) * 100);
    let percentMargin = Math.floor((25 * value) / 100);
    console.log(percentValue, percentMargin);
    if (value < 100) {
      progressBar.style.height = `calc(${value}% - ${percentMargin}px)`;
    } else if (value => 100) {
      progressBar.style.height = `calc(100% - 25px)`;
    } else {
      progressBar.style.height = `0px`;
    }
    if (percentValue < 50) {
      progressBar.style.backgroundColor = "red";
      progressContainer.style.borderColor = "red";
    } else {
      progressBar.style.backgroundColor = "green";
      progressContainer.style.borderColor = "green";
    }
  }
});
for (var i = 0; i < 4; i++) {
  var headdiv = document.getElementById('headdiv');
  var elem = document.querySelector('#mycontainer');
  var clone = elem.cloneNode(true);
  clone.id = 'mycontainer' + i;
  headdiv.appendChild(clone);
}
<div id="headdiv">
  <div id="mycontainer" style="width: auto;float: left;margin-left: 2%;">
    <input class="threshold" placeholder="threshold value" type="text" name="thresholdd" style="width: 120px; margin-top: 30px;margin-left: 0%; padding: 10px;" />
    <input class="live" placeholder="live value" type="text" name="livee" style="width: 120px; margin-bottom: 20px;padding: 10px;" />

    <div id="progress-container" class="progress-container">
      <div id="progress-bar" class="progress-bar"></div>
    </div>
  </div>
</div>

Answer №2

Make all the progress bars uniform by giving them the same class:

<div class="progress-bar"></div>

Create a variable and assign it to

document.querySelectorAll(".progress-bar")
- this will target all progress bars and return a Node list:

const bars = document.querySelectorAll(".progress-bar");

Iterate through each one using .forEach and attach an event listener to it:

bars.forEach(bar => bar.addEventListener("change", functionToRun);

Outcome: every progress bar now has a "change" event listener linked to it.

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

What is the best way to ensure my images are responsive to the varying device sizes when displayed on this website?

In my endeavor to design a 2-column layout using Bootstrap, I aim for each row to consist of two columns: One column will contain text, while the other will display images that complement the textual content. Below is the Bootstrap code snippet for the n ...

Enhancing Material UI KeyboardDatePicker with personalized CSS design

Material UI KeyboardDatePicker is the component I'm currently using. https://i.sstatic.net/It50L.png In order to remove the black line visible in the datepicker (as shown in the screenshot), what steps should I take? Displayed below is the code ...

Finding the main directory in JavaScript: a step-by-step guide

My website uses mod_rewrite to reformat the URLs like this: The issue arises when making AJAX calls to a file: I want to access login.php from the root without specifying the full URL or using the "../" method due to varying folder levels. So, I need a ...

The Best Approach for Angular Google Maps Integration

I'm diving into Angular for the first time while working on a project that requires advanced mapping functionality like clustering, routing, road routing, paths, directions, polygons, events, drawing on maps, info windows, markers, etc. After some re ...

I am sorry, but it seems like there is an issue with the definition of global in

I have a requirement to transform an XML String into JSON in order to retrieve user details. The approach I am taking involves utilizing the xml2js library. Here is my TypeScript code: typescript.ts sendXML(){ console.log("Inside sendXML method") ...

Tips for applying a custom design to your MUI V5 styled component

How do I customize the style of a button component in MUI V5? I've been trying to combine old methods with the new version, but it's not working as expected. import { Button } from "@mui/material"; import { styled } from "@mui/mate ...

What could be the reason for receiving [object object] from a JSON response?

Utilizing the datatables plugin, I am in need of refilling the table with ajax. To achieve this, I populate the table columns with the data retrieved from an ajax file (in json format) as shown in the following code snippet: $.get(select.data('url&a ...

Creating intricate JavaScript objects for JSON API integration can be accomplished by following these steps:

Here is a sample JSON structure used for querying an API: "order_items": [ { "menu_item_id": "VD1PIEBIIG", "menu_item_name": "Create Your Own", "modifiers": [ { "modifier_id ...

What could be causing my JavaScript loop to only display the final value?

Story Behind the Game In my latest project, I am delving into the world of creating a captivating 2D side-scrolling game using HTML and JavaScript. To ensure smooth gameplay, I have opted to incorporate ES6 for efficient management of all game objects. C ...

creating movement in a display of data points

(I'm just starting to learn about html5, so please keep it simple) I want to make a scatterplot of some data where the points move around over time. Right now, I am using context.arc() to create the initial frame of the animation with specific coord ...

Angular: Concealing a Component within a Controller

Being new to Angular, I am trying to figure out how to programmatically hide/show a component using the controller. I am having trouble understanding how to access my component and set ng-hide to false. Currently, my controller includes a service call. Af ...

What is the direction of auto-filling in CSS grid?

Here's an unusual query that I've been pondering. Despite checking various CSS documentation, I haven't found a clear answer yet. Take a look at this: https://i.sstatic.net/SglOl.jpg It resembles something like this grid-template-columns: ...

Discover the method for displaying a user's "last seen at" timestamp by utilizing the seconds provided by the server

I'm looking to implement a feature that displays when a user was last seen online, similar to how WhatsApp does it. I am using XMPP and Angular for this project. After making an XMPP request, I received the user's last seen time in seconds. Now, ...

Unable to retrieve values while mapping in next.js / react due to access restrictions

Hi there, I'm currently facing an issue with accessing specific values in a JSON object. Below is the code snippet that is causing the error: const Index = props => ( <Layout> <h1>Case Studies</h1> <ul> {props.caseS ...

Easily conceal and reveal elements using Svelte in a straightforward manner

I'm looking for a straightforward method to hide and show an element using a button in Svelte. Can someone guide me on how to achieve this? Additionally, I'm curious if it's easier to accomplish this task with vanilla JavaScript. ...

Error when accessing YouTube API Credentials - TypeError occurred: Unable to retrieve property '0' as it is undefined

I have encountered an issue with the YouTube API Browser key. I have two keys at my disposal, one that I created recently and another from a sample project where I obtained the code. The problem arises when I try to use my own key, as it seems to be ineffe ...

What is the best way to stack text boxes vertically in CSS/HTML?

How can I arrange these textboxes so that .textbox appears at the top, followed by textbox1 below? CSS .textbox { border: 1px solid #848484; -moz-border-radius-topleft: 30px; -webkit-border-top-left-radius: 30px; border-top-left-radius: ...

AngularJS directive failing to display the expected content

Recently delving into Angularjs, I've embarked on creating a directive. Here's a snippet from my js file: var app = angular.module('myCars',['ngResource']); app.controller('CarController', function (Post) { ...

Separating the login/register functionality from the main app using the MEAN Stack

Apologies for my poor English! I have developed an application using the MEAN stack (MongoDB + Express.js + Angular.js + Node.js) with authentication utilizing passport.js and JWT (jsonwebtoken and express-jwt). What I aim to achieve? The login and r ...

When state updates in React, the component will rerender without affecting its style

There seems to be a minor oversight on my part. The issue arises in the parent component where I maintain a state of selected items, which are added from the child component. The background color of the child component changes when an item is selected. Ad ...