Search code examples
javascriptdomeventsmootoolsmootools-events

Dom Element onclick (MooTools :: optionally)


Consider the following example:

function async_callback(array1, array2, array3) {
  // All arrays are equal length

  for(var i = 0; i < array1.length; i++) {
    var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': { 'click': function() { SomeFunction(array1[i], array2[i], array3[i] } }});
    $(document).appendChild(myElement);
  }
}

Now when I click my element, I get a null value for all three arguments. I even tried doing:

myElement.onclick = SomeFunction; // but this won't allow arguments

I know I can create a string and use eval() and that does work, but I don't like eval().

Any ideas?

BTW: This is a simple example to replicate the problem, and not actual code.


Solution

  • This is your handler:

    function() { SomeFunction(array1[i], array2[i], array3[i] } }
    

    By the time its executed, the loop will have completed and i will therefore be equal to the length of the array, as per the conditional statement (i < array1.length) and the iteration statement (i++).

    The easiest way to resolve this is to wrap the handler in an additional immediately-executed function, and pass i to it, -- this will have the effect of retaining the value of i in a new closure:

    for(var i = 0; i < array1.length; i++) {
        var myElement = new Element('div', { 'id': 'dvMy' + i, 'events': {
            'click': (function(i){
                return function() { SomeFunction(array1[i], array2[i], array3[i] } };
             }(i))
        });
        $(document).appendChild(myElement);
    }