I want the nav to hide scrolling down 60px and to show when scrolling up 60px, no matter in which part of the page.
I did this, but it's incomplete, what am I missing?
<script>
let y = 0;
</script>
<svelte:window bind:scrollY="{y}" />
<nav class:hideNav={y > 60}>
<ul>
<li>link</li>
</ul>
</nav>
<style>
nav {
position: fixed;
top: 0;
}
.hideNav {
top: -70px;
}
</style>
Your code seems to perfectly hide the navbar after you scroll the specified amount, here is a REPL of your code in action. maybe the body of your content has no scroll ?
here is another implementation REPL that further elaborates how to use scrolling position
<script>
import {onMount, onDestroy} from 'svelte'
const scrollNavBar = 60
let show = false
onMount(() => {
window.onscroll = () => {
if (window.scrollY > scrollNavBar) {
show = true
} else {
show = false
}
}
})
onDestroy(() => {
window.onscroll = () => {}
})
</script>
<style>
.scrolled {
transform: translate(0,calc(-100% - 1rem))
}
nav {
width: 100%;
position: fixed;
box-shadow: 0 -0.4rem 0.9rem 0.2rem rgb(0 0 0 / 50%);
padding: 10px;
transition: 0.5s ease
}
:global(body) {
margin: 0;
padding: 0;
height: 200vh;
}
</style>
<nav class:scrolled={show}>
elemnt
</nav>
In your REPL, it seems like the nav does not reappear on scrolling up. It does appear only at the top of the page.
I am also trying to show the nav when the user scrolls up by 30px anywhere on the page, for instance. I think that it was what OP is asking as well.
I found a REPL successfully doing it with jQuery but I am struggling to make it work in Svelte at the moment. Any clue?
I will revert back if I succeed.
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
The answers here couldn't help me. So here's a REPL I made for what I'm using to achieve this in svelte:window.
How I did it;
Create a variable that will store the scroll position (in px) at the end of the scroll event - [let's call it lastScrollPosition].
let lastScrollPosition = 0
At the beginning of a scroll event; inside svelte:window, get and compare the current scroll position to the last scroll position variable we created in [1.] (lastScrollPosition)
<svelte:window on:scroll={()=>{
var currentScrollposition = window.pageYOffset || document.documentElement.scrollTop; //Get current scroll position
if (currentScrollposition > lastScrollPosition) {
showNav = false
}else{
showNav = true
}
lastScrollPosition = currentScrollposition;
}}></svelte:window>
If current scroll Position is greater than lastScrollPosition, showNav is false else, true.
NB: You can use CSS or Svelte Conditional ({#if}) to achieve the hide on scroll down and show on scroll up (This example shows CSS..).
<main>
<div class="nav {showNav == true? "show": "hide" }" >
Nav bar
</div>
<div class="content">
Content
</div>
</main>
<style>
.nav{
background-color: gray;
padding: 6px;
position: fixed;
top: 0;
width: 100%;
}
.content{
background-color: green;
margin-top: 25px;
padding: 6px;
width: 100%;
height: 2300px;
}
.hide{
display: none;
}
.show{
display: unset;
}
</style>
Related
I'm trying to make my header disappear when scrolling down and only re-appear when scrolling up. I can't get it to work:
http://jsfiddle.net/mxj562qt/
Any ideas where I'm going wrong?
HTML:
<div id="header" class="custom-header">
This is your menu.
</div>
<main>
This is your body.
</main>
<footer>
This is your footer.
</footer>
Javascript:
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $("#header").outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$("#header").addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
}
lastScrollTop = st;
}
CSS:
body {
padding-top: 40px;
}
#header {
background: #f5b335;
height: 50px;
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
main {
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
It would appear that the CSS class doesn't get added but I'm not sure why. Am I referencing the Div in the wrong way?
So, I can see that the issue stems from this bit of code ...
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
In my tests, the doc height was always > than the st + window height.
I did this ...
// Scroll Up
console.log('doc height: ', $(document).height());
console.log('st+window height: ', st + $(window).height());
if(st + $(window).height() < $(document).height()) {
$("#header").removeClass('nav-up');
}
// results from scrolling up + down
// doc height: 2058
// st+window height: 313
// doc height: 2058
// st+window height: 280
// doc height: 2058
// st+window height 1614
// doc height: 2058
// st+window height: 1580
Changing the aforementioned JS to this seems to get you where you need to be.
$("#header").removeClass('nav-up');
Then your CSS needed some work ...
I noticed that your top element wasn't applying due to the CSS selector priority.
.nav-up {
top: -50px !important;
}
The result: scrolling down, the nav bar hides, scrolling up, the navbar shows.
I forked your code below;
http://jsfiddle.net/itsbjk/aw6qb2mr/16/
The problem here is with your CSS. You have specified position:fixed; in your code and that bit of CSS overrides all the JS you are writing. Fixed will force your header to be visible no matter what you are doing. Instead, you could try this in your CSS:
body {
padding-top: 40px;
}
#header {
background: #f5b335;
height: 50px;
position: absolute;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
main {
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
The absolute property should make it disappear on scrolling. And also, your referencing of the <div> tag isn't wrong!
I have fixed sidebar which should scroll along with main content and stop at certain point when I scroll down. And vise versa when I scroll up.
I wrote script which determines window height, scrollY position, position where sidebar should 'stop'. I stop sidebar by adding css 'bottom' property. But I have 2 problems with this approach:
When sidebar is close to 'pagination' where it should stop, it suddenly jumps down. When I scroll up it suddenly jumps up.
When I scroll page, sidebar moves all the time
Here's my code. HTML:
<div class="container">
<aside></aside>
<div class="content">
<div class="pagination"></div>
</div>
<footer></footer>
</div>
CSS:
aside {
display: flex;
position: fixed;
background-color: #fff;
border-radius: 4px;
transition: 0s;
transition: margin .2s, bottom .05s;
background: orange;
height: 350px;
width: 200px;
}
.content {
display: flex;
align-items: flex-end;
height: 1000px;
width: 100%;
background: green;
}
.pagination {
height: 100px;
width: 100%;
background: blue;
}
footer {
height: 500px;
width: 100%;
background: red;
}
JS:
let board = $('.pagination')[0].offsetTop;
let filterPanel = $('aside');
if (board <= window.innerHeight) {
filterPanel.css('position', 'static');
filterPanel.css('padding-right', '0');
}
$(document).on('scroll', function () {
let filterPanelBottom = filterPanel.offset().top + filterPanel.outerHeight(true);
let bottomDiff = board - filterPanelBottom;
if(filterPanel.css('position') != 'static') {
if (window.scrollY + window.innerHeight - (bottomDiff*2.6) >= board)
filterPanel.css('bottom', window.scrollY + window.innerHeight - board);
else
filterPanel.css('bottom', '');
}
});
Here's live demo on codepen
Side bar is marked with orange background and block where it should stop is marked with blue. Than you for your help in advance.
I solved my problem with solution described here
var windw = this;
let board = $('.pagination').offset().top;
let asideHeight = $('aside').outerHeight(true);
let coords = board - asideHeight;
console.log(coords)
$.fn.followTo = function ( pos ) {
var $this = this,
$window = $(windw);
$window.scroll(function(e){
if ($window.scrollTop() > pos) {
$this.css({
position: 'absolute',
top: pos
});
} else {
$this.css({
position: 'fixed',
top: 0
});
}
});
};
$('aside').followTo(coords);
And calculated coordinates as endpoint offset top - sidebar height. You can see solution in my codepen
I would like to create vertically a fixed navigation bar for my site. Currently i use the one that has been mentioned on various posts here:
HTML:
<html>
<head>
src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="{% static 'navbar.css' %}">
<script type="application/javascript">
$(document).ready(function () {
var navPos = $('.nav_menu').offset().top; //Sticky navbar
$(window).scroll(function () {
var scrollPos = $(this).scrollTop();
if (scrollPos >= navPos) {
$('.nav_menu').addClass('fixed');
} else {
$('.nav_menu').removeClass('fixed');
}
});
});
</script>
.....
<div class="nav-container">
<div class="nav_menu">
Bars go here
....
And CSS:
.nav-container .nav_menu.fixed {position: fixed; z-index: 10000; top: 0; width: 195px; padding-left: 8px}
This solution works great, the navbar is sticked, in my case the navbar is on the top left side of the page. If i scroll down it perfectly follows the scroll. In case i open the gape using a small window and i stoll down plus right the bar follows (as it should happen). However i would like the bar to only follow vertically, in case someone scrolls left or right the bar should stay where it is.
How can i achieve this?
You can stop the horizontal fixed by applying minus left scroll:
var $window = $(window);
var navPos = $('.nav_menu').offset().top; //Sticky navbar
$window.scroll(function() {
var scrollPos = $window.scrollTop();
var left = 0 - $window.scrollLeft();
if (scrollPos >= navPos) {
$('.nav_menu').addClass('fixed').css('left', left + 'px');
} else {
$('.nav_menu').removeClass('fixed').css('left', 0);
}
});
body,
html {
height: 1000px;
width: 2000px;
position: relative;
margin: 0;
padding: 0;
}
.nav_menu {
height: 50px;
background-color: blue;
width: 195px;
}
.fixed {
position: fixed;
top: 0;
left: 0;
z-index: 2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br><br><br>
<div class="nav_menu"></div>
I want to hide the bootstrap navbar when I scroll down but show the bootstrap navbar when I scroll upwards.
This is a common Navbar reaction on most mobile phone apps, for instance on Whatsapp.
I successfully coded the desirable effect in an HTML page which you'll find attached. I can't get it to work in my meteor App, or don't know how to get it to work on my meteor App, hence me looking for a meteor package.
Does anyone know how I can get the code below to work in a meteor environment?
html:
<header class="navbar-default">
This is your menu.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"> </script>
<script type="text/javascript" src="javaScript.js"></script>
<link rel="stylesheet" href="style.css">
</header>
<main>
This is your body.
</main>
<footer>
This is your footer.
</footer>
And below the CSS file:
body {
padding-top: 40px;
}
/*
header {
background: #f5b335;
height: 40px;
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
*/
.navbar-default{
background-color: #ea5b31;
border-color: #ea5b31;
margin-bottom: 0px;
height: 50px;
position: fixed;
top: -1px;
width: 100%;
transition: top 0.2s ease-in-out;
}
.nav-up {
top: -40px;
}
main {
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAPklEQVQYV2O8dOnSfwYg0NPTYwTRuAAj0QqxmYBNM1briFaIzRbi3UiRZ75uNgUHGbfvabgfsHqGaIXYPAMAD8wgC/DOrZ4AAAAASUVORK5CYII=
) repeat;
height: 2000px;
}
footer { background: #ddd;}
* { color: transparent}
And a version of my JavaScript file:
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('header').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 250);
function hasScrolled() {
var st = $(this).scrollTop();
// alert("st VALUE is: " +st);
// Make sure they scroll more than delta
if(Math.abs(lastScrollTop - st) <= delta)
return;
// If they scrolled down and are past the navbar, add class .nav-up.
// This is necessary so you never see what is "behind" the navbar.
if (st > lastScrollTop && st > navbarHeight){
// Scroll Down
$('header').removeClass('navbar-default').addClass('nav-up');
// alert("You are scrolling down!");
// alert(+st+ " > " +lastScrollTop+ " && " +st+ " > " +navbarHeight);
} else {
// Scroll Up
if(st + $(window).height() > $(document).height()) {
// alert(+st+ " + " +$(window).height()+ " < " +$(document).height() )
$('header').removeClass('nav-up').addClass('navbar-default');
}
}
lastScrollTop = st;
}
I've got the following code for a sticky header, but I can't get the scroll to work and it's not a smooth transition. The #top-nav-wrapper barely scrolls when the fixed header below is activated:
<script>
$(document).scroll( function() {
var value = $(this).scrollTop();
if ( value > 48 ) {
$(".header").css("position", "fixed");
$("body").css("padding-top", "90px");
} else {
$(".header").css("position", "relative");
$("body").css("padding-top", "0");
}
});
</script>
The 48 value is the height of the #top-nav-wrapper, plus it has a box-shadow.
The .header class with the search bar is what should remain.
The basic html:
<div class="headerWrapper">
<div id="top-nav-wrapper"></div>
<div class="header"></div>
</div>
The CSS:
body {
background: #EEE;
}
#top-nav-wrapper {
width: 100%;
position: relative;
box-shadow: 0px 1px 1px 0px #B8B8B8;
z-index: 2001;
background: #EEE;
}
.header {
position: relative;
left: 0;
top: 0;
width: 100%;
min-height: 90px;
z-index: 2000;
background: #EEE;
height: 90px;
box-shadow: 0px 1px 2px #C4C4C4;
}
* I tried the following suggestion, but it's the same effect as before:
<script>
$(window).scroll( function() {
var value = $(this).scrollTop();
var $body = $('body');
var docked = $body.hasClass('docked');
if ( value > 48 ) {
if( !docked ) {
$body.addClass('docked');
}
} else {
if( docked ) {
$body.removeClass('docked');
}
}
});
</script>
Any ideas appreciated.
Update - I've changed the script to the following and placed it in the head - this resolves the top nav not scrolling dynamically and I added a placeholder div after the header and before the content with the same size height as the fixed header to keep the content where it should be (because the fixed header changes the natural flow), but there's still the lag/jump when the fixed header kicks in.
Placeholder CSS:
.headerPlaceholder {
height: 90px;
width: 100%;
display: none;
}
Solution to top nav not scrolling all the way after 48px scroll height was set:
<script>
$(document).ready(function () {
var div = $('.header');
var div2 = $('.headerPlaceholder');
var start = $(div).offset().top;
$.event.add(window, "scroll", function () {
var p = $(window).scrollTop();
$(div).css('position', ((p) > start) ? 'fixed' : 'static');
$(div).css('top', ((p) > start) ? '0px' : '');
$(div2).css('display', ((p) > start) ? 'block' : 'none');
});
});
</script>
To make it a smooth transition, there might need to be a slight delay and fadein/out effect, if anyone could help with that?
You can try
$(window).scroll( function() {
var value = $(this).scrollTop();
var $body = $('body');
var docked = $body.hasClass('docked');
if ( value > 48 ) {
if( !docked ) {
$body.addClass('docked');
}
} else {
if( docked ) {
$body.removeClass('docked');
}
}
});
CSS
.docked {
padding-top: 90px;
}
.docked .header {
position: fixed;
z-index: 2005;
}
You can be more efficient if there is an overall container you can target instead of body.