Javascript - dynamically assign onclick event in a loop

I have a very simple html page with js code:

<html> <head> <title></title> </head> <body> <div id="divButtons"> </div> <script type="text/javascript"> var arrOptions = new Array(); for (var i = 0; i < 10; i++) { arrOptions[i] = "option" + i; } for (var i = 0; i < arrOptions.length; i++) { var btnShow = document.createElement("input"); btnShow.setAttribute("type", "button"); btnShow.value = "Show Me Option"; var optionPar = arrOptions[i]; btnShow.onclick = function() { showParam(optionPar); } document.getElementById('divButtons').appendChild(btnShow); } function showParam(value) { alert(value); } </script> </body> </html> 

This page links 10 buttons, but when you press any button, it always shows the warning โ€œoption9โ€. How can I set an onclick event to display the corresponding option !?

Thanks!

+8
javascript html events button onclick
source share
7 answers

You will need to do something like this:

 btnShow.onclick = (function(opt) { return function() { showParam(opt); }; })(arrOptions[i]); 
+28
source share

Consider the fact that when the onclick () function is executed, all that it has is:

 showParam(optionPar); 

verbatim. The optionPar parameter will be enabled at the time the click event is executed, and at the moment it will most likely be the last value that you assigned to it. You should usually avoid passing variables this way.

The problem you are trying to solve is best solved by rewriting the fragment, for example:

  btnShow.value = "Show Me Option"; var optionPar = arrOptions[i]; btnShow.optionPar = optionPar; btnShow.onclick = function(e) { // if I'm not mistaking on how to reference the source of the event. // and if it would work in all the browsers. But that the idea. showParam(e.source.optionPar); } 
+2
source share

I am attaching an event handler:

  window.onload = function() { var folderElement; tagFolders = document.getElementById("folders"); for (i = 0; i < folders.length; i++) { folderElement = folderButtons[i]; folderElement = document.createElement("button"); folderElement.setAttribute("id", folders[i]); folderElement.setAttribute("type", "button"); folderElement.innerHTML = folders[i]; if (typeof window.addEventListener !== "undefined") { folderElement.addEventListener("click", getFolderElement, false); } else { folderElement.attachEvent("onclick", getFolderElement); } tagFolders.appendChild(folderElement); } 

which can extract something from the element that raised the event:

 // This function is the event handler for the folder buttons. function getFolderElement(event) { var eventElement = event.currentTarget; updateFolderContent(eventElement.id); } 

in this case you need to embed the option inside the element / tag. In my case, I use an identifier.

+1
source share

For jquery, check out the event adding data section from the API :

 ... for (var i = 0; i < arrOptions.length; i++) { $('<input id="btn" type="button" value="Show Me Option"><input>').appendTo("#divButtons") $('#btn').bind("click", { iCount: i}, function(event) { showParam(arrOptions[iCount]); }); } 
+1
source share

The accepted answer seems to work, but seems to be a confusing and somewhat cumbersome way to do this. A better way might be to use the data attribute for the element for which you want to assign an event listener. This is a simple, understandable and easy way. Here is an example:

 btnShow.data = arrOptions[i]; btnShow.onclick = function() { showParam(this.data); } 
+1
source share

The accepted answer is correct, but I feel that there was no real explanation.

Let me try to explain, the problem here is in the classic missing closure.

The variable "i" is incremented by 1 for each iteration of the loop, and the on-click event is not actually executed , whether it applies only to the element a, it is summed up to the length of arrOptions, which is equal to 10.

So, the loop continues until โ€œiโ€ becomes equal to 10, then, whenever the on-click event fires, it takes on the value i, which is equal to 10.

now, for the solution, in the solution we use closure, so when we apply the value 'i' to the on-click event for element a, it actually gets the exact value of i in time.

The onclick event's internal function creates a closure where it refers to the parameter (arrOptions [i]), which means that the actual i-variable is at the right time.

The function eventually closes automatically with this value, and then can return its corresponding value when the on-click event is executed.

+1
source share

You only pass the variable reference to the function, not its value. Therefore, every time the loop repeats, it assigns a link to your anonymous function, and they all point to the same value in memory. But since you use the same variable name in a loop, you overwrite the value of the variable. You can bind a variable to a string to preserve its value. For example, for example:

 btnShow.onclick = new Function("", "showParam(" + arrOptions[i] + ");"); 

The first parameter is the name of the function, but afaik is optional (it can be left blank or omitted altogether).

0
source share

All Articles