tags:

views:

76

answers:

3

I am working in a technology which supports javascript but minus "this" keyword (and few other limitations; one of them is that it does not support Event object). Now the only way to work with it to set Id to every element. But when I work with ajax and place the information in different elements using the code below:

 //var obj; //already been set to valid json object and suppose it has 10 elements (currencies names)
 var container = document.getElementById('container');

 for(i = 0; i < obj.length; i++){
  var div = document.createElement('div');
  var a = document.createElement('a');

  a.setAttribute('href', '#');
  a.setAttribute('id' , 'opt_' + i);
  a.setAttribute('onclick', function(){convert('opt_' + i);}); //<---Problem

  a.textContent = obj[i].name;

  div.appendChild(a);
  container.appendChild(div);
 }

 function convert(event_source){
  //use event_source to determine which element (anchor) was clicked
 }

then all the anchors have onclick="convert('opt_9');" Please suggest a solution to come over this problem. Please keep in mind that I can not use "this" or "event.which".

+1  A: 

It is because your counter i is being captured in the closures you set up. The i is not being evaluated when you create the closure, it is evaluated when the closure is run. If you call the onclick, they will all look at the loop counter after the loop has finished. You need to make a copy.

var j = i;
a.setAttribute('onclick', function(){convert('opt_' + j);});

Or maybe in this case (even though I am usually against string onclicks):

a.setAttribute('onclick', "convert('opt_"+i+"')");
Thilo
+3  A: 

Use a closure. Also see Creating closures in loops: A common mistake

a.onclick = function(n) {
    return function() {
        convert('opt_' + n);
    } 
}(i);

See all related questions.

Anurag
+1  A: 

Working (as expected) version of your code:

 var container = document.getElementById('container');
 for(i = 0; i < obj.length; i++){
    (function(){
        var div = document.createElement('div');
        var a = document.createElement('a');
        a.setAttribute('href', '#');
        a.setAttribute('id' , 'opt_' + i);
        a.setAttribute('onclick', function(){convert('opt_' + i);}); //<---Problem
        a.textContent = obj[i].name;
        div.appendChild(a);
        container.appendChild(div);
     })()
 }
 function convert(event_source){
  //use event_source to determine which element (anchor) was clicked
 }
Anurag posted a great link for description why...

Zango