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
Post a Comment