0

I have JS that creates dynamic elements. I want to add onclick events to these elements and pass the calling element's ID to the event handler so that I can use JS to change the text of the element that is clicked.

I do that by doing something like this inside a loop:

 var btnID = "button-" + x; // unique id for changing element inside of test()

 /* desired result is <button onclick="test(<runtime value of btnID>)"></button> */
 buttonElement.onclick = function () { test(btnID)  };

Unfortunately, the result is that every button element passes the btnID of the last element in the loop to test(). Can someone explain why this happens?

https://jsfiddle.net/j519rbyn/1/

TurgidWizard
  • 619
  • 1
  • 7
  • 22

2 Answers2

1

So in your above code what happens is because the click event happens in future within the time the for loop has been executed so thats why you get the last value which got executed to x. So we are getting every time button-2 as text. Value 3 won't come since it gets break at the condition of for loop.

So in order to avoid this problem you can use IIFE, which is called immediately invoked function expression.

In your code snippet, i found two things based on the jsfiddle that you have added.

First One is you are trying to put a text in the button it should be innerHTML not innerTest.

Second one is the issue the below snippet way you can avoid this one using IIFE.

function bootstrap() {
  var parentContainer = document.getElementById("parent");

  for (var x = 0; x < 3; x++) {
    var buttonElement = document.createElement("button");
    buttonElement.innerHTML = "click me " + x;
    (function() {
      var j = "button-" + x
      buttonElement.onclick = function() {
        test(j)
      }
    })()

    parentContainer.appendChild(buttonElement);
  }

}

function test(elementID) {
  alert(elementID);
}

bootstrap()
<div id="parent">


</div>

I hope you have clear idea on this.

Learner
  • 8,379
  • 7
  • 44
  • 82
  • Brilliant thank you, I had suspected the cause, but couldn't think of any alternative! Nifty – TurgidWizard Jun 06 '20 at 19:06
  • Welcome Turgid, happy to help kindly vote if it solved your issue. So it will be helpful for others for future reference. – Learner Jun 07 '20 at 06:18
0

It is because everytime when you click the button the btnID value is called which is the last id in the loop.Try this code

buttonElement.onclick = function () { 
var btnID = "button-" + x; 
test(btnID)  
};
Hari
  • 114
  • 1
  • 14
  • @ Hari, this will give you the response as button-3, because the value which x has 3 till the execution ends up, you need to use iife to resolve this issue, its because the event calls at future before that for loop has done execution – Learner Jun 06 '20 at 17:37