5

I just want the #menu to fade when the scroll bar is moving to provide a less cluttered interface. Is there code that would allow this?

I guess basically what I'm looking for is how to grab the scroll bar movement event. To slowly fade out the #menu after 1 seconds of scrolling and bring back the #menu after 2 second of scroll-bar inactivity.

Thank you so much!

Mohammad
  • 7,344
  • 15
  • 48
  • 76

3 Answers3

5
var $menu = $("#menu");
var opacity = $menu.css("opacity");
var scrollStopped;

var fadeInCallback = function () {
    if (typeof scrollStopped != 'undefined') {
        clearInterval(scrollStopped);
    }

    scrollStopped = setTimeout(function () {
        $menu.animate({ opacity: 1 }, "slow");
    }, 2000);
};

$(window).scroll(function () {
    if (!$menu.is(":animated") && opacity == 1) {
        $menu.animate({ opacity: 0 }, "slow", fadeInCallback);
    } else {
        fadeInCallback.call(this);
    }
});

http://jsfiddle.net/zsnfb/9/

This sets the scroll event to do a few things. First it clears a timeout to fade the menu div back in. After that, if the menu isn't already faded out, it fades the menu out and sets the timeout in the callback. If the menu is already faded out, it just sets the timeout. If the user stops scrolling, the menu will fade back in after 2 seconds.

There are other solutions that use fadeOut() and fadeIn(). My only issue with those functions in this case is that setting display: none; to the menu div will affect the layout of the page, where setting visibility: hidden; or opacity: 0; shouldn't affect the layout.

btleffler
  • 972
  • 7
  • 13
  • nice example! but do you know why it doesn't work here? http://jsfiddle.net/zsnfb/ – Mohammad Sep 12 '11 at 17:54
  • 1
    My mistake! You can't clear an interval that doesn't exist yet! My answer has been updated. – btleffler Sep 12 '11 at 19:25
  • I'm marking this the better answer since it takes account for the consequent scroll events firing at the same time and preventing a function call overload. p.s. you're missing a semicolon after the fadeInCallback definition : ) – Mohammad Sep 12 '11 at 20:57
  • Sorry for adding a 'thank you' comment, but this is a great answer and really helped me out - I had been searching through stack for the right solution. – DBUK Dec 12 '12 at 10:28
3

Right using the following:

$('body').scroll(function(){
    $('#menu').fadeOut();

    var scrollA = $('body').scrollTop();

    setTimeout(function(){
        if(scrollA == $('body').scrollTop()){
            $('#menu').fadeIn();
        }
    }, 200);
})

So we record the scroll amount, wait 200 milliseconds and then see if the scroll has changed, if not we fade the menu back in.

Tom Walters
  • 15,366
  • 7
  • 57
  • 74
  • May I ask why you have the fade in function inside the scroll event? Will it even fire? Thank you! – Mohammad Sep 12 '11 at 16:48
  • Obviously, the fade in won't happen unless it's faded out first. The checks need to be made inside the Fade out function. – Dan Hanly Sep 12 '11 at 16:51
  • jQuery allows you to nest functions, and yes it does fire. Take a look at: http://jsfiddle.net/LJVMH/ for an example of this implementation. – Tom Walters Sep 12 '11 at 16:53
  • Thank you, I guess it was my misunderstanding of how functions work. I thought.. how could you be checking for the scrollTop to be the same inside a scroll event itself?! That is what had me confused. Thank you both for the clarification! And excellent example! – Mohammad Sep 12 '11 at 16:55
  • @Tom Walters: Do you know how to avoid the overflow of fade in fade out functions when the scroll bar is moved erratically, causing the box to fade in and fade out numerous times even after the scroll bar has halted? The timeout causes there to be pause in the function finishing and thus, causing a backed up set of unfinished fires, gradually firing one after the other even after the event has finished long ago. I would really appreciate this. You can test it, in your demo by moving the scroll bar quickly. – Mohammad Sep 12 '11 at 17:59
  • Because of the way the animation is handled we can't is ply use stop(), soi would suggest increasing the time delay from 200 to 500 - this should prevent any noticeable build up. – Tom Walters Sep 12 '11 at 20:57
0

I think this is what you are looking for http://jsfiddle.net/wfPB6/

Abdul Kader
  • 5,781
  • 4
  • 22
  • 40