Have been struggling with Javascript closure for a while trying to wrap brain around function scopes, but I think they're wrapping around me instead. I've looked at a number of posts (Nyman's was the most helpful) but obviously still don't get it. Trying to run a loop over the hover method in jQuery. Need hover functions to ultimate trigger more than one action each, but would be happy to get them working with a single image swap each for now.
$(document).ready(function() {
imageSource = [];
imageSource[0] = 'images/img0.png' //load 0 position with "empty" png
imgArea = [];
for (var i=1; i<11; i++) {
(function( ){ //anonymous function for scope
imageSource[i] = 'images/img' + i + '.png';
imgArea[i] = '#areamap_Img' + i;
// running console.log here gives expected values for both
$(imgArea[i]).hover( //imgArea[i] (selector) works correctly here
function() {
$('#imgSwap').attr('src',imageSource[i]); // imageSource[i] is undefined here
},
function() {
$('#imgSwap').attr('src','images/img0.png');
});
})(); // end anonymous function and execute
}; // for loop
});
Tried the idea of using an anonymous function for scoping from another jQuery post. Seems to work OK but throws an undefined for the array value in the first hover function, I guess because it's an inside function (hardcoded image sources work correctly there).
Have been struggling with Javascript closure for a while trying to wrap brain around function scopes, but I think they're wrapping around me instead. I've looked at a number of posts (Nyman's was the most helpful) but obviously still don't get it. Trying to run a loop over the hover method in jQuery. Need hover functions to ultimate trigger more than one action each, but would be happy to get them working with a single image swap each for now.
$(document).ready(function() {
imageSource = [];
imageSource[0] = 'images/img0.png' //load 0 position with "empty" png
imgArea = [];
for (var i=1; i<11; i++) {
(function( ){ //anonymous function for scope
imageSource[i] = 'images/img' + i + '.png';
imgArea[i] = '#areamap_Img' + i;
// running console.log here gives expected values for both
$(imgArea[i]).hover( //imgArea[i] (selector) works correctly here
function() {
$('#imgSwap').attr('src',imageSource[i]); // imageSource[i] is undefined here
},
function() {
$('#imgSwap').attr('src','images/img0.png');
});
})(); // end anonymous function and execute
}; // for loop
});
Tried the idea of using an anonymous function for scoping from another jQuery post. Seems to work OK but throws an undefined for the array value in the first hover function, I guess because it's an inside function (hardcoded image sources work correctly there).
Share Improve this question asked May 11, 2009 at 13:24 boomturnboomturn 9712 gold badges12 silver badges14 bronze badges1 Answer
Reset to default 11There is indeed a problem with your closures, and it has to do with your usage of the var i
. Since your anonymous function has no local version of i
, it's using the version of the function above it. However, when it tries to access i
at a later date, i
== 11 (since that's what made the loop terminate). To fix this, you need to declare a local version of i
in each anonymous function, like this:
for (var i=1; i<11; i++) {
(function( ){ //anonymous function for scope
var index = i; // The important part!
// It's not technically necessary to use 'index' here, but for good measure...
imageSource[index] = 'images/img' + index + '.png';
imgArea[index] = '#areamap_Img' + index;
$(imgArea[index]).hover(
function() {
$('#imgSwap').attr('src',imageSource[index]); // Here's where `index` is necesssary.
},
function() {
$('#imgSwap').attr('src','images/img0.png');
});
})(); // end anonymous function and execute
}; // for loop
Additionally, there's a small problem in your code you should fix just for good measure. You're not accessing your local variables correctly; you should use:
var imageSource = [];
var imageSource[0] = 'images/img0.png' //load 0 position with "empty" png
var imgArea = []
Without the "var", you're declaring and accessing global variables. (If this is your intended behavior then I apologize.)