thejerkstore
thejerkstore

Reputation: 231

How to hide/show nav bar when user scrolls up/down

Hide/show nav bar when user scrolls up/down

Here's the example I'm trying to achieve: http://haraldurthorleifsson.com/ or http://www.teehanlax.com/story/readability/

The navigation bar slides up off screen when you scroll down and slides back down on screen when you scroll up. I've figured out how to do it with fade in/fade out but I would like to achieve it with the exact same animation as in the example. Note: I already tried SlideIn() and like the way that it does the stretching animation...

JQUERY:

var previousScroll = 0,
headerOrgOffset = $('#header').offset().top;

$('#header-wrap').height($('#header').height());

$(window).scroll(function() {
    var currentScroll = $(this).scrollTop();
    console.log(currentScroll + " and " + previousScroll + " and " + headerOrgOffset);
    if(currentScroll > headerOrgOffset) {
        if (currentScroll > previousScroll) {
            $('#header').fadeOut();
        } else {
            $('#header').fadeIn();
            $('#header').addClass('fixed');
        }
    } else {
         $('#header').removeClass('fixed');   
    }
    previousScroll = currentScroll;
});

CSS:

#header {
    width: 100%;
    z-index: 100;
}

.fixed {
    position: fixed;
    top: 0;
}

#header-wrap {
    position: relative;
}

HTML:

    <div id="header-wrap">
    <div id="header" class="clear">
        <nav>
            <h1>Prototype</h1>
        </nav>
    </div>
</div>

Upvotes: 16

Views: 53906

Answers (6)

Dani Amsalem
Dani Amsalem

Reputation: 1616

I found a similar and simpler implementation of @Dom Day written about by Saijo George.

NOTE: I renamed Saijo's variables so it would be easier for me to read.

CSS

/* This class will be attached to your nav by the below */
.scrollUp {
  transform: translateY(-100%);
}

jQuery

const navbar = document.querySelector("nav"); //Select your nav element here
let previousScroll = 0;

$(window).scroll(function handleNav() {
  let currentScroll = $(window).scrollTop(); //Distance scrolled down the page
  let navHeight = $(navbar).height(); //Height of navbar

  //When scrolling down AND you've scrolled past navHeight * 2.25, add .scrollUp
  if (currentScroll > previousScroll && currentScroll > navHeight * 2.25) {
    $(navbar).addClass("scrollUp");
    //When scrolling up AND you've scrolled less than navHeight, remove .scrollUp
  } else if (previousScroll > currentScroll && !(currentScroll <= navHeight)) {
    $(navbar).removeClass("scrollUp");
  }
  previousScroll = currentScroll;
});

Upvotes: 0

Sandeep Mukherjee
Sandeep Mukherjee

Reputation: 771

css

@media(min-width: 1079px){
    #header{
        width:100%;
        height:82px;
        border:1px solid grey;
        background-color: lightgreen;
        margin:0 auto;
        position:fixed;
        transition-property: all;
        transition-duration: 0.3s;
        transition-delay: 0s;
        transition-timing-function: ease-out;
    }
    nav{
        display: flex;
        justify-content: space-between;
    }
    nav .nav1{
        list-style-type: none;
        padding: 0px;
    }
    nav a{
        text-decoration: none;
        color:grey;
        padding: 13px;
        display: block;
        color: grey;
        margin-top: 15px;
    }
    a{
        text-decoration: none !important;
    }
    nav a:hover{
        color: red;
    }
    nav .nav1{
        display: flex;
        justify-content: flex-end;
    }
    .row2{
        background-color: skyblue;
        height:2000px;
        margin-top: 82px;
    }
}

html

<!DOCTYPE html>
<html>
<head>

    <title>header2</title>
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
   <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
    <link rel="stylesheet"  href="css/header-larger1.css">
</head>
<body>
    <!--<div id="header">-->
        <nav>
            <ul class="nav1" id="header">
                <li><a href="">HOME</a></li>
                <li><a href="">ABOUT</a></li>
                <li><a href="">INFO</a></li>
                <li><a href="">DISCOUNTS</a></li>
                <li><a href="">BUSINESS</a></li>
                <li><a href="">BLOG</a></li>
                <li><a href="">CONTACT</a></li>
            </ul>
        </nav>
    <!--</div>-->
    <div class="container row2">
        <h3>this is row2</h3>
    </div>
</body>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="js/head1.js"></script>
</html>

js

function fun1()
{
     var documentElem=$(document),

     lastScrollTop=0;
     scrollabc=80;

     documentElem.on('scroll',function()
     {
        var currentScrollTop=$(this).scrollTop();
        console.log(window.pageYOffset);
        if(currentScrollTop > scrollabc)
        {
            if(currentScrollTop>lastScrollTop)
            {
           //nav.addClass('hidden'); 
            document.getElementById("header").style.marginTop = "-80px";
            console.log("first if block");
            }
        else
        {
          // nav.removeClass('hidden'); 
           document.getElementById("header").style.marginTop = "0px";
           console.log("2nd if block");
        } 
    }
        lastScrollTop=currentScrollTop;
    })
}



fun1();

Upvotes: 0

Abouasy
Abouasy

Reputation: 896

Try headroom js.

Also you can edit the CSS classes and deploy the transition effect.

http://wicky.nillia.ms/headroom.js

Upvotes: 1

lukeed
lukeed

Reputation: 469

Whatever navbar element you use, it has to include a transition: transform 0.3s on it, and a base transform of 0.

#navbar {
    position: fixed;
    right: 0; left: 0; top: 0; 
    /* your height */
    height: 40px;
    /* .... */
    -webkit-transform: translate3d(0,0,0);
    -moz-transform: translate3d(0,0,0);
    transform: translate3d(0,0,0);
    -webkit-transition: -webkit-transform .3s;
    -moz-transition: -moz-transform .3s;
    -o-transition: transform .3s;
    transition: transform .3s;
}
#navbar.scrolled {
    /* subtract your height */
    -webkit-transform: translate3d(0,-40px,0);
    -moz-transform: translate3d(0,-40px,0);
    transform: translate3d(0,-40px,0);
}

Then your javascript needs to watch the user's scrolling:

;(function (){
    var previousScroll = 0;
    var navbar = document.getElementById('navbar'),
        navClasses = navbar.classList; // classList doesn't work <IE10

    window.addEventListener('scroll', function(e){
       var currentScroll = window.scrollY;
       var isDown = currentScroll > previousScroll;

       if ( isDown && !navClasses.contains('scrolled') ){
          // scrolling down, didn't add class yet
          navClasses.add('scrolled'); // we hide the navbar
       } else if ( !isDown ){
          // scrolling up
          navClasses.remove('scrolled'); // won't error if no class found
       }

       // always update position
       previousScroll = currentScroll;
    });
}()); //run this anonymous function immediately

Upvotes: 2

Dom Day
Dom Day

Reputation: 2562

To get the inner content of the nav to slide up instead of being progressively hidden, you need to do the animation on the parent element, and keep the inner element at the bottom of the parent, like so:

jsfiddle

<div id="header-wrap">
    <div id="header" class="clear">
        <nav><h1>Prototype</h1>another line<br/>another line
        </nav>
    </div>
</div>

css

body {
    height: 1000px;
}

#header {
    width: 100%;
    position: absolute;
    bottom: 0;
}

#header-wrap {
    width: 100%;
    position: fixed;
    background-color: #e0e0e0;
}

js

var previousScroll = 0,
    headerOrgOffset = $('#header').height();

$('#header-wrap').height($('#header').height());

$(window).scroll(function () {
    var currentScroll = $(this).scrollTop();
    if (currentScroll > headerOrgOffset) {
        if (currentScroll > previousScroll) {
            $('#header-wrap').slideUp();
        } else {
            $('#header-wrap').slideDown();
        }
    } else {
            $('#header-wrap').slideDown();
    }
    previousScroll = currentScroll;
});

Upvotes: 15

James
James

Reputation: 1572

Have you tried animate? but replace the -60px with the height of the navbar. But negative.

$(window).scroll(function() {
    var currentScroll = $(this).scrollTop();
    console.log(currentScroll + " and " + previousScroll + " and " + headerOrgOffset);
    if(currentScroll > headerOrgOffset) {
        if (currentScroll > previousScroll) {
            $('#header').animate({
                 top: '-60px'      //Change to Height of navbar
            }, 250);               //Mess with animate time
        } else {
            $('#header').animate({
                 top: '0px'
            },250);
            $('#header').addClass('fixed');
        }
    } else {
         $('#header').removeClass('fixed');   
    }
    previousScroll = currentScroll;
});

Upvotes: 2

Related Questions