Reputation: 177701
I so often run into this pattern.
Can someone please give me a canonical way of only getting image1 once - if you look at example two, it works - but I fail to understand why. An explanation of this specific situation is appreciated, I have read the closure stuff on the net :)
Initial code:
$(document).ready(function() {
$("#prev, #next").click(function() {
var mainImage = $("#image1");
if (mainImage.css("visibility")=="hidden") {
$(mainImage.css("visibility","visible");
return;
}
var currentNumber = parseInt(mainImage.attr("src").split('gallery/')[1]);
var newNumber = ($(this).attr("id")=="next")?currentNumber+1:currentNumber-1;
var testImage = new Image();
testImage.onload=function() {
var img = $("#image1");
img.attr("src",this.src);
img.css("visibility","visible");
}
testImage.onerror=function() {
$("#image1").css("visibility","hidden");
}
testImage.src="gallery/"+newNumber+".jpg";
return false;
});
});
Attempting a closure - why does it work - or is this just a scoping issue?
$(document).ready(function() {
$("#prev, #next").click(function() {
var mainImage = $("#image1"); // this should be local to the click function
if (mainImage.css("visibility")=="hidden") {
$(mainImage.css("visibility","visible");
return;
}
var currentNumber = parseInt(mainImage.attr("src").split('gallery/')[1]);
var newNumber = ($(this).attr("id")=="next")?currentNumber+1:currentNumber-1;
var testImage = new Image();
testImage.onload=function() {
mainImage.attr("src",this.src); // how come mainImage is available here?
mainImage.css("visibility","visible");
}
testImage.onerror=function() {
mainImage.css("visibility","hidden");// how come mainImage is available here?
}
testImage.src="gallery/"+newNumber+".jpg";
return false;
});
});
Upvotes: 0
Views: 71
Reputation: 5579
This is how JavaScript scoping works. Take a look at the following:
var func1 = function(){
console.log(i + 2);
};
var myFunc = function(){
var i = 1;
var func2 = function(){
console.log(i + 2);
};
func2(); // output 3
func1(); // ReferenceError: i is not defined
};
Upvotes: 1
Reputation: 18344
In javascript, vars live in the scope of the function where it has been defined, and the 'subfunctions' (local functions) inside this function.
For example:
function fun1(){
var var1 = "Defined in fun1. ";
function fun2(){
var var2 = "Defined in fun2. ";
alert(var1); //Alerts "Defined in fun1 "
function fun3(){
alert(var1 + var2); //Alerts "Defined in fun1. Defined in fun2";
}
}
alert(var2); //Alerts 'undefined' (fun1 doesn't know var2 exists)
}
And the same is happening in your code. Your variable mainImage
'lives' in every local function. Don't forget that binded functions are also local functions, even if they don't have name or are declared differently.
Hope this helps. Cheers
Upvotes: 1
Reputation: 11824
mainImage is defined with var so it becomes global for all functions
Upvotes: 0