Fade in/Fade out, Fixed/Sticky Header

Jamie Smith picture Jamie Smith · Nov 7, 2012 · Viewed 8.4k times · Source

Okay, I know it seems like I've asked this question already, for which @adeneo had previously answered and apreciated, however I am rattling my brains because I just can't get this to work.

I'm trying to make my 'fixed' positioned header 'fadeTo' 0.5 Opacity when scrolled down and fade back to full opaqueness ('opacity': 1.0) when the user scrolls back to the top?

Here's what I have:

$(window).on('scroll', function() {
if ($(this).scrollTop() > 50) {
$("#header").fadeTo(400, 1);
}else{
$("#header").fadeTo(400, 0.5);

}
});

At the moment, using this code only seems to make it 'fadeTo' 0.5 opacity when scrolled down but it then won't fade back to full opaqueness (opacity: 1.0) when scrolled back to the top.

Please help!

Answer

Fabrício Matté picture Fabrício Matté · Nov 7, 2012

One of the problems is that you're executing an animation of 400ms for every time your user scrolls the page, this generates a very long queue of effects which have no visible effect, e.g. animating to 1 opacity for each time the scroll event fires with scrollTop > 50, adding a very long queue of invisible effects until the fading out effect takes place.

A simple way to remedy that is using .stop(true) before executing the fadeTo, this way the element effects queue will be always cleared before executing the given animation.

$(window).on('scroll', function() {
    if ($(this).scrollTop() > 50) {
        $("#header").stop(true).fadeTo(400, 0.5);
    } else {
        $("#header").stop(true).fadeTo(400, 1);
    }
});

Fiddle

But even so you will still be executing animations unnecessarily, so I'd recommend using .data to store the faded state and only animate when necessary:

$(window).on('scroll', function() {
    var header = $("#header");
    if ($(this).scrollTop() > 50) {
        if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(400, 0.5);
    } else if (header.data('faded')) {
        header.data('faded', 0).stop(true).fadeTo(400, 1);
    }
});

Fiddle

ps. I've inverted your opacity values as your question's code's logic didn't correspond to your desired behavior.