Paul van den Dool
Paul van den Dool

Reputation: 3212

Change top value of fixed element depending on scroll

I like to create an effect where my navigation bar hides when scrolling down, but appears when scrolling up, no matter how far you scrolled down. I've managed to get as far as this jsfiddle, but I'm lost from there. The navigation div has position: fixed with top: 0. I decrease the top for every number of pixels scrolled down. But at the moment, I'm not having the insight to increase top for every number of pixels scrolled UP, no matter how far down you scrolled.

I hope it's clear enough what I try to achieve.

jQuery

var topScroll = 0;
$(document).scroll(function () {
    var scrolled = $(this).scrollTop();
    if (scrolled > $('nav').height()) {
        $('nav').css('top', ($('nav').height() - scrolled));
    }
    if (topScroll > scrolled) {
        //scrolling up
    } else {
        //scrolling down
    }
    topScroll = scrolled;
});

-

Edit

I think I need a way of saving the scrollTop() value when the scroll direction is changed and then add the difference between that number and the new scrollTop() to the top value of my navbar. I just don't know how to do that.

Upvotes: 1

Views: 2683

Answers (2)

Mx.
Mx.

Reputation: 3665

Similar to luidgi27's code but with a smooth animation :)

-> altered Fiddle

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
        $('nav').animate({height: "0px"}, 100);
   } else {
       $('nav').animate({height: "50px"}, 100);
   }
   lastScrollTop = st;
});

Edit

Im not sure what you want. Changed the Code a bit so it has steps while showing the Nav.

-> new altered Fiddle

var lastScrollTop = 0;
var height = 50;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop && height > 0){
        $('nav').animate({height: "-=25px"}, 30);
       height = height - 25;
   } else if(st < lastScrollTop && height < 50){
       $('nav').animate({height: "+=25px"}, 30);
       height = height + 25;
   }
   lastScrollTop = st;
});

Edit2

-> new altered Fiddle 2

Here you go with the third and most accurate hiding effect.

var lastScrollTop = 0;
var diffrence = 0;
var height = 50;
var isGrowing = false;
var isShrinking = false;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
    diffrence = st - lastScrollTop;
    $('#debug').html(diffrence + "<br />" + height + "<br />" + $('nav').height());
   if (diffrence > 0 && height < 50 && !isGrowing){
       if((diffrence + height) > 50){
           height = 50;
           isGrowing = true;
           $('nav').stop().animate({height: "50px"}, 100, function(){
           isGrowing = false;
           });
       }else{
           height = height + diffrence;
            $('nav').animate({height: "+="+diffrence+"px"}, 0);
       }
   } else if(diffrence < 0 && $('nav').height() > 0 && !isShrinking){
       if((diffrence + height) < 0){
           height = 0;
           isShrinking = true;
           $('nav').stop().animate({height: "0px"}, 100, function(){
           isShrinking = false;
           });
       }else{
           height = height + diffrence;
           diffrence = diffrence*-1;
           $('nav').animate({height: "-="+diffrence+"px"}, 0)
       }       
   }
   lastScrollTop = st;
});

Upvotes: 0

luidgi27
luidgi27

Reputation: 324

Is this what you want ?

var lastScrollTop = 0;
$(window).scroll(function(event){
   var st = $(this).scrollTop();
   if (st > lastScrollTop){
        $('nav').css('display', 'none');
   } else {
       $('nav').css('display', 'block');
   }
   lastScrollTop = st;
});

Upvotes: 1

Related Questions