3

Here's my code:

function test(e, f) {
    for (var i = 0; i < e.length; i++) {
        $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>")
        $('#op' + i).click(function () {
            f[i]();
        })
    }
}


$(function postPunk() {
    var func1 = function () {
        alert('1');
    }
    var func2 = function () {
        alert('2');
    }
    var func3 = function () {
        alert('3');
    }
    test(['Option1', 'Option2', 'Option3'], [func1, func2, func3]);
})

The click events aren't calling the functions. If I place an alert test in the click event, it fires fine.

Any ideas why this isn't working? It seems to be a problem with passing the array of functions as a parameter. Is there a better way to do this?

9
  • 2
    didn't know ; was optional in javascript. You are missing them at line 6, and the last line. Commented Aug 17, 2012 at 18:12
  • Are you looking at it in a console? There's an error: TypeError: [3] is not a function "f"+[i](); Commented Aug 17, 2012 at 18:12
  • stackoverflow.com/questions/477700/array-functions-in-jquery Check the above question. This may help you. Commented Aug 17, 2012 at 18:15
  • There's more "missing" ; than that (each of the function expressions). They are "optional", but it is best not to leave them off. Commented Aug 17, 2012 at 18:17
  • 1
    @WouterH Explicit semicolons are optional in most places in JavaScript (for code that is already written cleanly with one-statement per line). This will not cause any problems with the above code. Look up "ASI" (Automatic Semicolon Insertion) for the rules. I write almost no semicolons in JavaScript; know the rules and be consistent. Commented Aug 17, 2012 at 18:21

4 Answers 4

8

As with every other question of this type, i keeps on changing.

Instead, try this:

for( var i=0; i<e.length; i++) {
    (function(i) {
        // your code that depends on i not changing
    })(i);
}
Sign up to request clarification or add additional context in comments.

1 Comment

@JaredFarrish Nope, because f doesn't change like i does.
4

This seems to be the classic JavaScript issue, where they all be the last value (or undefined since f[3] doesn't exist), since that's the value of i after the loop.

Try to pass the function reference directly to the click handler.

function test(e, f) {
    for (var i = 0; i < e.length; i++) {
        $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>")
        $('#op' + i).click(f[i])
    }
}

Or, another solution is to make a function that returns a function. This will allow it to "close" around i.

function test(e, f) {
    var makeFunc = function(i) {
        return function() {
            f[i]();
        }
    };
    for (var i = 0; i < e.length; i++) {
        $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>")
        $('#op' + i).click(makeFunc(i))
    }
}

1 Comment

+1 For passing the function directly to .click. If i is not needed, this is the only sensible solution.
1

The code in the callback function uses the value of i after the loop has ended, so it points to an index outside the array. You need a closure in the loop so that each iteration gets its own instance of the variable:

function test(e, f) {
  for (var i = 0; i < e.length; i++) {
    $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>");
    (function(i){
      $('#op' + i).click(function () {
        f[i]();
      });
    })(i);
  }
}

Comments

0

Here's how I got it to work: http://jsfiddle.net/fH2Dk/3/

function test(e, f){    
     for(var i = 0; i < e.length; i++) {
         (function(i) {
            $('#clickme').append("<button id='op" + i + "'>" + e[i] + "</button>");
            $('#op' + i).click(function(){
                f[i]();
            });
        })(i);    
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.