Why does the alert coming from my loop always retu

2020-07-11 08:02发布

问题:

I have a some buttons, which are stored in an array. I then loop through that array to add a click event to each button. Each click alerts the value of i. I expect the values to be 1, 2, 3 and so on, but they always come back as one value, in case 3.

Can you explain why this happens and how to fix it?

Please see this a jsFiddle. Code below:

var theButtons = ['.button.one', '.button.two', '.button.three'];

for (i=0; i<theButtons.length; i++) {
    $(theButtons[i]).click(function () {
        alert(i); // always returns 3
    });
}

Please explain it as simply and clearly as you can - I'm somewhat of a beginner at Javascript and programming.

回答1:

By the time you click on the button i === 3. Need to pass the value of i into a closure:

for (var i = 0; i<theButtons.length; i++) { // do `var i` so the i is not global
    (function(index){
        $(theButtons[i]).on('click', function () {
           alert(index); // index === the value that was passed
        });
    })(i); // pass the value of i
}

Fiddle Demo: http://jsfiddle.net/maniator/fE55Y/3/



回答2:

Just use EACH method:

$( ".button" ).each(function( index ) {
    $(this).click( function(e){
        alert( index + ": " + $(this).text());
    });
});

Fiddle: http://jsfiddle.net/fE55Y/4/

Update:

Agreed that .each() is not needed for what's been asked. Here's the one without using .each() method.

$(".button").click(function () {
    alert("Button Index: " + $(this).index());
});


回答3:

Welcome to asynchronous programming and global variables!

The problem you are seeing here is because of the fact that i is declared globally in this case, in that is accessible from anywhere by anything.

So, what happens when your script is executed is:

  • Loop through the array of classnames
  • On each iteration, bind a click to the matching node, calling the anonymous function you provided

The problem here is that the function you provided is executed outside of your loop (e.g. when the click happens), so the value of i is whatever it was in the last iteration, in this case 2