Reputation: 3880
My question is about the example on this page: http://api.jquery.com/event.data/
<button> 0 </button>
<button> 1 </button>
<button> 2 </button>
<button> 3 </button>
<button> 4 </button>
<div id="log"></div>
JS:
var logDiv = $( "#log" );
for ( var i = 0; i < 5; i++ ) {
$( "button" ).eq( i ).on( "click", { value: i }, function( event ) {
var msgs = [
"button = " + $( this ).index(),
"event.data.value = " + event.data.value,
"i = " + i
];
logDiv.append( msgs.join( ", " ) + "<br>" );
});
}
In this demo, when I click one of the buttons, the output is like the following:
button = 0, event.data.value = 0, i = 5
what I don't understand is why "i = 5" here, shouldn't "i" be equal to "0" in this case?
Upvotes: 0
Views: 136
Reputation: 92933
That's the point. When the code is run, five different event handlers are set. Here's what the first event handler looks like from the JS engine's point of view:
$("button").eq(0).on("click", {value: 0}, function(event) { /* i set to zero */
var msgs = [
"button = " + $(this).index(),
"event.data.value = " + event.data.value, /* passed in via {value: 0} */
"i = " + i /* i remains a variable inside the callback function */
];
logDiv.append( msgs.join( ", " ) + "<br>" );
});
Note that i
isn't set to zero inside the callback function; it remains a variable. And at the time that event handler is called (when the button is clicked), the for
loop is complete and i=5
.
To do what you imagine should take place, we'd need to wrap the inside of the loop in a closure:
for (var i = 0; i < 5; i++) {
(function (i) { /* start of closure */
$("button").eq(i).on("click", function (event) {
var msgs = [
"button = " + $(this).index(),
"i = " + i];
logDiv.append(msgs.join(", ") + "<br>");
});
})(i); /* end of closure */
}
http://jsfiddle.net/mblase75/qeXn5/
...or just use event.data.value
instead of i
.
Upvotes: 0
Reputation: 245
The event listeners hold a reference to the "i" variable, which is used in the for statement. This value will be 5 after the for loop has ended and all the "click" listeners are being added: it is the latest value being set in "i++" before failing the condition "i < 5".
Upvotes: 0
Reputation: 227270
This is because the i
you are referencing when you do "i = " + i
is the same i
that's being incremented in the for
loop.
When the loop ends, and when your click event is finally triggered, i
will have been incremented to 5. When you pass it as event.data
, you are "capturing" the current value, so that's why you get 0.
Upvotes: 1