1

we are trying to implement simple hiding menu when scroll, and showing back when user stops scrolling, but .on('scroll') works but .off('scroll') doesn't

$(document).on('scroll',hideMenu);
$(document).off('scroll',showMenu)
function hideMenu(){
     $('#home_menu').fadeOut();
}
function showMenu(){
     $('#home_menu').fadeIn();
}

what is happening? when we start scrolling menu fades away, but when we stop scrolling, it doesn't fade it

runningmark
  • 738
  • 4
  • 13
  • 32
  • 1
    Did you try to read the jQuery API documentation? – MysterX Feb 27 '16 at 09:41
  • 3
    [`jQuery.off`](http://api.jquery.com/off#entry-longdesc) is used to remove a handler, so that it wont be call anymore for that event. – t.niese Feb 27 '16 at 09:41
  • 'on' addEventListener, and 'off' delete it – sglazkov Feb 27 '16 at 09:42
  • 2
    Check this question [jQuery scroll() detect when user stops scrolling](http://stackoverflow.com/questions/9144560/jquery-scroll-detect-when-user-stops-scrolling) – t.niese Feb 27 '16 at 09:43
  • Read the accepted solution [here](http://stackoverflow.com/questions/9144560/jquery-scroll-detect-when-user-stops-scrolling) – S.A Feb 27 '16 at 09:43
  • @t.niese I was 4 seconds too late :) – S.A Feb 27 '16 at 09:44

2 Answers2

3

You can use a setTimeout instead, that will be canceled (cleared) each time there is a scroll, and when the scroll stops, make it execute showMenu :

var menuTimer;
$(window).on("scroll", hideMenu);

function hideMenu()
{
    clearTimeout(menuTimer);
    $('#home_menu').fadeOut();
    menuTimer = setTimeout(showMenu, 900);
}

function showMenu()
{
    $('#home_menu').fadeIn();
}
body{padding-top:3em;font-family:Arial,Helverica,sans-serif}
#home_menu{position:fixed;top:0;left:0;width:100%;padding:1em;background:#1b83db;color:#fff}
p{margin-bottom:3em}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="home_menu">Menu</div>

<p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p><p>Some text</p>
blex
  • 24,941
  • 5
  • 39
  • 72
  • that was some precise answer, i would loved the native version(i guess it doesn't exists) but if it's working i've no problem :) – runningmark Feb 27 '16 at 14:17
  • @runningmark Sorry for the delay, but what do you mean by "native version"? Without jQuery? Or the equivalent of what you wanted `.off('scroll')` to do? – blex Feb 29 '16 at 11:33
  • i apologies for not being clear, with native i meant without using intervals :) – runningmark Mar 02 '16 at 06:32
0

There is a misunderstanding here:

.off("scroll") does not mean that a callback has to be invoked when the scroll ends.

Instead it detach the callback from the scroll event.

What you want is invoke a callback when the scroll starts, invoke another one when it stops.

There are many ways to accomplish this.

This is my approach (the code is self-explaining):

$(document).on('scroll',scrollStart);

// A scroll has started

function scrollStart()
{
    var lastScrollY;

    // record the position

    lastScrollY = $(window).scrollTop();

    // hide the menu

    hideMenu();

    // detach the event. We don't want the callback called again for now.

    $(document).off('scroll',scrollStart);

    // let the function scrollRunning be called after 1 sec

    setTimeout( function() { scrollRunning( lastScrollY ) }, 1000 );
}

// A scroll is going on. Or maybe has ended

function scrollRunning( lastScrollY )
{
    var currentScrollY;

    // current scroll position

    currentScrollY = $(window).scrollTop();

    // did the position change ? Scroll is going on
    // schedule scrollRunning to check again after 1 sec

    if( lastScrollY != currentScrollY ) // Scrolling is going on
    {
        lastScrollY = currentScrollY;
        setTimeout( function() { scrollRunning( lastScrollY ) }, 1000 );
    }
    else // Scrolling has stopped. Show the menu and reattach the event
    {
        $(document).on('scroll',scrollStart);
        showMenu();
    }
}
Paolo
  • 15,233
  • 27
  • 70
  • 91