2

I have a situation like this one:

talenti = $(".talenti");
filtra = $(".filtra");
wrapNavHeight =  $("#wrapNav").outerHeight(true);
filtra.click(function(e) {
    e.preventDefault();
    $(".nasco").hide();
    $("#sliding-navigation").delay(delay).show();
    delay += 500;
    talenti.removeClass('opened');
    filtra.addClass('opened');
    filtra.attr('id',"focF");
    talenti.attr('id',"");
    if (filtra.hasClass("opened")) {
        $("#wrapNav").slideToggle("100", "linear", function(){
            alert(wrapNavHeight);
            $("#container").animate({"height": "+=wrapNavHeight"}, 100,function(){
                $(".box").animate({"top": "+=wrapNavHeight"});
            });
        });
    } 
});

I am trying to get wrapNavHeight but alert(wrapNavHeight); outputs null; can't then assign that value to the next animate lines

Anyone?

rob.m
  • 9,843
  • 19
  • 73
  • 162
  • check `$("#wrapNav").outerHeight(true);`, what does it return? is `wrapNav` id right? – davioooh Feb 03 '12 at 08:42
  • #wrapNav is indeed an id. At the very start if I check its value with an alert it will return null as it is display: none; but I am then using slideToggle and it does expand it and reveal it so its height then be defined when I ask its value in the alert as per the above code but for some reasons it still return null – rob.m Feb 03 '12 at 08:44
  • I second what David C. suggested - most probably `outerHeight()` returns `null` - which could mean that you call it on an empty set of elements - i.e. `#wrapNav` points to noting (http://api.jquery.com/outerHeight/). But it may also depend on the jQuery version you are using - there were some bugs related to it, like [this one](http://bugs.jquery.com/ticket/7693) – Tomasz Zieliński Feb 03 '12 at 08:51

3 Answers3

2

isn't it just that you are assigning the variable the value of outerHeight at the time it's not visible? I think you need to re-evaluate outerHeight after the toggle transition. Replace

alert(wrapNavHeight);

with

alert($("#wrapNav").outerHeight(true));

see if that's any better?

dfsq
  • 191,768
  • 25
  • 236
  • 258
Mike Simmons
  • 1,298
  • 1
  • 9
  • 22
  • You are perfectly right and not just makes sense but it does return the correct value. Any idea why the global var i assign at the top, wrapNavHeight, it is no read by the animate? At the animate point $("#wrapNav").outerHeight(true) (which is defined as wrapNavHeight at the top) is a value as alert says when using your suggeston – rob.m Feb 03 '12 at 08:56
  • not entirely sure what you're trying to do here, but if you're trying to add wrapNavHeight to #container height, then something like this might do it: – Mike Simmons Feb 03 '12 at 09:05
  • var newHeight = $("#container").height() + $("#wrapNav").outerHeight(true); – Mike Simmons Feb 03 '12 at 09:06
  • sorry, prematurely hit return :) – Mike Simmons Feb 03 '12 at 09:07
  • right ok, yes it does what I'm looking for, newHeight is now the new and correct #container height, however can you see I have a second animate? The top: "value" should be the same as new added container height (basically the current $("#wrapNav").outerHeight(true); ) – rob.m Feb 03 '12 at 09:14
  • $("#container").animate({height: newHeight}, 100,function(){ $(".box").animate({top: newHeight}); }); – Mike Simmons Feb 03 '12 at 09:27
  • mm nope, that would set the top distance as the height of #container + #wrapNav outerHeight, we only want to add the current #wrapNav outerHeight – rob.m Feb 03 '12 at 09:31
  • added this as another variable just below the previous defined one (newHeight): var newDistance = newHeight - $("#container").height(); then to my second animate I did: $(".box").animate({top: newDistance}); it works great, just thinking if there is a shorter way rather than defining a new var to achieve this, otherwise it's fine, it works. Thanks a lot – rob.m Feb 03 '12 at 09:34
  • One thing i would do is assign a variable to each jQuery element your are using so you don't have to traverse the DOM each time you are recalculating the heights, so create variables for $('#container'), $('#wrapNav'), etc – Mike Simmons Feb 03 '12 at 09:40
0

Nobody else actually explained why this happens. Here's why:

It depends on:

  • which object is used as "this" for invocation of the function containing all the code above
  • which object is used as "this" for invocation of the function defined starting on line 4 of your code

In JavaScript, "global" references actually apply to the current this object (or to the "true" global object (window in web browsers) if not within a function)

Thus, if the this objects for the 2 functions I pointed out above are different, then you'll get the situation you observed.

In the browser, the default this object is usually window, but this can be changed when the function is run, such as by passing a different parameter to apply or by calling the function as a method.

Been a year since I used jQuery seriously, but if I recall right, jQuery event handlers usually rebind this to something useful related to the event (using apply-- you can do this too).

So, assuming the outer function's this hasn't been bound to anything special other than window, simply replace wrapNavHeight with window.wrapNavHeight in the inner function to achieve your desired effect.

(In practice I wouldn't actually do this, though, as a matter of style. Just declare wrapNavHeight as a var within the outer function instead, and then you'll get lexical scoping.)

Domingo Ignacio
  • 1,194
  • 7
  • 13
-1

Try searching.

jQuery global variable best practice & options?

Community
  • 1
  • 1
akiller
  • 2,462
  • 22
  • 30