Jason Allan Jason Allan - 1 year ago 59
Javascript Question

Injecting elements and attaching Click event handlers in a loop with javascript

I'm trying to make a dropdown which is populated from an array with javascript. Each Item needs to have an event trigger attached, but it currently only attaches the event to the last element. I have tried the examples based on fixing closures but is still only attaches to the last element.


var ArrayUName = ["A","B","C"]
var ArraySlug = ["Q","W","E"]
for (i = 0; i < ArrayUName.length; i++) {
var GoalID = ArrayUName[i] + '-' + ArraySlug[i];
document.getElementById("TheContent").innerHTML +=
'<a class="GoalIDBtn" id="' + GoalID + '">' + ArrayUName[i] + ' / ' + ArraySlug[i] + '</a></br>';
(function(_i, _GoalID)
function() {alert("Click Made : " + _i)}
})(i, GoalID);
console.log("Loop #" + i);

Answer Source

That's because innerHTML is a destructive property. It recreates the set content and creates new elements, the newly generated elements do no have any click handlers bound to them. You should create a node (element) instead of using innerHTML.

You can use the document.createElement and HTMLElement.appendChild methods instead:

var a = document.createElement('a');
a.className = 'GoalIDBtn';
a.id = GoalID;
a.textContent = ArrayUName[i] + ' / ' + ArraySlug[i];
(function(_i /*, _GoalID*/) {
  a.addEventListener("click", function() {
      alert("Click Made : " + _i);

Here is a demo on jsfiddle. Note that it doesn't add the br elements and you can use the similar DOM APIs for creating them.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download