html - How do I dynamically create events and event handlers in javascript -


i'm trying create buttons dynamically unique listeners , handlers using loop, unfortunately must doing wrong because last button works. more surprising fact when clicking last button instead of "button no.3" returns "button no.4"

bellow code , here jsfiddle http://jsfiddle.net/y69jc/4/

html:

<body>     <div id="ui">     text ...     </div> </body> 

javascript:

var uidiv = document.getelementbyid('ui'); uidiv.innerhtml = uidiv.innerhtml + '<br>';  var results = ["button one","button two","button three","button four"];  for(var n=0;n<results.length;n++) {  uidiv.innerhtml = uidiv.innerhtml + '<button id="connect'+n+'">option'+n+':'+results[n]+'</button><br>';  var tempid = document.getelementbyid('connect'+n);  tempid.addeventlistener('click', function(){console.log("button no."+n)}, false); } 

thanks!

it's classic case when need closure: change to:

var uidiv = document.getelementbyid('ui'); uidiv.innerhtml = uidiv.innerhtml + '<br>';  var results = ["button one", "button two", "button three", "button four"];  (var n = 0; n < results.length; n++) {     // note: not use .innerhtml. create new element programatically     //       , use .appendchild() add parent.     var button = document.createelement('button');     button.id = 'connect' + n;     button.textcontent = 'option' + n + ':' + results[n];      uidiv.appendchild(button);      button.addeventlistener('click', /* inline function */ (function (n2) {         // here we'll use n2, equal current n value.         // value of n2 not change block, because functions         // in js create new scope.          // return actual 'click' handler.         return function () {             console.log("button no." + n2)         };     })(n)); // invoke current n value } 

the reason for loop not create scope, "button no. " + n evaluated n equal number of elements in results array.

what has done create inline function accepting n parameter , call immediately current value of n. function return actual handler click event. see this answer nice , simple example.

edit: code using innerhtml property add new buttons in loop. broken because every time assign using uidiv.innerhtml = ..., deleting contents present in div , re-creating them scratch. caused ripping off event handlers attached. schematically, looked this:

uidiv.innerhtml = ""  // first iteration of for-loop uidiv.innerhtml === <button1 onclick="...">  // second iteration of for-loop // 'onclick' handler button1 disappeared uidiv.innerhtml === <button1> <button2 onclick="...">  // third iteration of for-loop // 'onclick' handler button2 disappeared uidiv.innerhtml === <button1> <button2> <button3 onclick="..."> 

Comments

Popular posts from this blog

java - activate/deactivate sonar maven plugin by profile? -

python - TypeError: can only concatenate tuple (not "float") to tuple -

java - What is the difference between String. and String.this. ? -