Reputation: 231
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
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
Reputation: 771
@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;
}
}
<!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>
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
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
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
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:
<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
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