2

I want the footer be just below the window in the initial position and when I resize the window. I need to declare the var outside and again inside the function to make it work. Is it ok or there is a better way to do it?

$(function(){

    // initial position:    
    var docHeight = $(window).height();
    $('#footer').css('margin-top', docHeight + 'px');

    // position when I resize the window:
    $(window).resize(function() { 
    var docHeight = $(window).height();
        $('#footer').css('margin-top', docHeight + 'px');
    });

})

I have the code here to play: http://jsfiddle.net/dWpp5/

Nrc
  • 9,577
  • 17
  • 67
  • 114
  • 7
    never trust w3fools... – Christoph Nov 19 '12 at 15:39
  • 3
    [w3schools is so well known for erroneous information that it's common to cite w3fools](http://w3fools.com/). – zzzzBov Nov 19 '12 at 15:42
  • This concept got nothing to do with jQuery, this is pure JavaScript issue. In your example code, `docHeight` will become global since you're setting it without `var`. You can see it clearly in [this fiddle](http://jsfiddle.net/dWpp5/1/), it's even available in inline button click event. What exactly are you asking? – Shadow The GPT Wizard Nov 19 '12 at 15:44
  • 1
    Forget global variables, and learn how scope works, and you'll figure this out yourself without globals. You do of course realize that the variable you declared outside the resize function will always hold the same value, as it won't be updated unless you reset it inside the resize function (which you have commented out ?). – adeneo Nov 19 '12 at 15:44
  • So what's the question? You've made `docHeight` global because you didn't use `var`. See [here](https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#Declaring_variables). But as @adeneo suggested, you should really understand scope and avoid globals. If you made `docHeight` local, you'll still be able to use it in your resize function because of closure. Since your resize function is declared within you doc ready function, it will be able to access all the local variables of the outer scope. – Matt Burland Nov 19 '12 at 15:46
  • 1
    One of the most classic and useful threads on SO - http://stackoverflow.com/questions/500431/javascript-variable-scope – Jay Blanchard Nov 19 '12 at 16:02

2 Answers2

2

JavaScript has "Function scope". So like you said if you define a variable with the "var" keyword it become local to whatever function block it is inside. Anything outside of that function cannot see it.

However if you don't use "var" to define a variable or use "var" but outside of a function - it is a global variable that any function or expression has access to.

The cool thing about function scoping is that while noting outside of that function can see the variable - any functions that are executed or defined inside of the parent function does.

The hole goes deep - if you use a variable in a function, and the function doesn't see it defined inside of itself, it goes to its parent to see if it's defined there. If it doesn't it find a definition - it goes to its parent's parent - and so on and so forth until it reaches the global scope - if it doesn't find a definition on the global scope the variable is declared in the global scope.

Here's a Smashing Magazine article on scoping.

tbwiii
  • 506
  • 3
  • 10
  • In my example, if I don't repeat the var inside the resize function it does not work. It seems it does not get the var from its parent? – Nrc Nov 19 '12 at 16:18
  • I think I understand your explanation about scope. It is clear and well explained. I update the question to make it more clear: in my example I need to use the the var twice to make the effect I am looking for. Is it correct or there is a better way to do it? – Nrc Nov 19 '12 at 16:39
  • You should be able to take out this line " var docHeight = $(window).height();" in your in resize's anonymous function – tbwiii Nov 19 '12 at 17:01
  • If I take it it does not work. You can try it yourself in the Fiddle I provided http://jsfiddle.net/dWpp5/ I suppose that as Matt says it is needed to update de docHeight – Nrc Nov 20 '12 at 08:05
1

This works just as well:

$(function(){

    // initial position:    
    // this is a variable local to the doc ready function
    var docHeight = $(window).height();
    $('#footer').css('margin-top', docHeight + 'px');

    // position when I resize the window:
    $(window).resize(function() { 
        // since this function is contained within the outer function, 
        // the docHeight local from the outer scope is accessible here.
        $('#footer').css('margin-top', docHeight + 'px');
    });
})

// Here, however, docHeight is NOT accessible.
Matt Burland
  • 44,552
  • 18
  • 99
  • 171
  • If I use your code here jsfiddle.net/dWpp5 the footer does not update his position on resize window. It needs the var to be repeated in the resize function. Perhaps I did not explain well the problem, I updated the question. – Nrc Nov 19 '12 at 16:41
  • @Nrc: So it sounds like you complaint isn't about variable scope, but about updating the value. When you do `var docHeight = $(window).height()`, the function returns a number that is *copied* to the variable. If the window height then changes, the value in `docHeight` will NOT be updated. You will need to call the `.height()` function again. – Matt Burland Nov 19 '12 at 16:46
  • @Nrc: See [this fiddle](http://jsfiddle.net/dWpp5/3/), is this what you were trying to do? – Matt Burland Nov 19 '12 at 16:48