I'm using this basic tutorial to show/hide a standard BS4 navbar on scroll, and it works great for desktop.
However, on mobile the navbar is acting a little strange when scrolling down, then going back to the top. Once back to the top, the navbar hides again.
I suspect the issue has something to do with scrollTop() but can't seem to troubleshoot this one.
Here's my JS:
if ($('.smart-scroll').length > 0) { // check if element exists
var last_scroll_top = 0;
$(window).on('scroll', function() {
var scroll_top = $(this).scrollTop();
if(scroll_top < last_scroll_top) {
$('.smart-scroll').removeClass('scrolled-down').addClass('scrolled-up');
} else {
$('.smart-scroll').removeClass('scrolled-up').addClass('scrolled-down');
}
last_scroll_top = scroll_top;
/* Tried to catch for scroll_top zero, but doesn't help */
if(scroll_top == 0) $('.smart-scroll').removeClass('scrolled-up');
});
}
And, here's my CSS:
.smart-scroll {
position: fixed !important;
top: 0;
right: 0;
left: 0;
z-index: 1000;
transition: all 0.3s ease-in-out;
}
.scrolled-down {transform:translateY(-100%);}
.scrolled-up {transform:translateY(0);}
I also tried incorporating this stackoverflow and still couldn't get it working.
Any ideas to get this operational on mobile?
Had something similar in my practices. Took code from there and adapted to your case.
if ($('.smart-scroll').length > 0) {
var lastScrollTop = 0;
$(window).scroll(function() {
var scroll_top = $(window).scrollTop();
if (scroll_top > 1) { // think, this will work a little bit better to catch scrolltop more then 0(1)
$(".smart-scroll").addClass("stick");
} else {
$(".smart-scroll").removeClass("stick");
}
if (scroll_top > lastScrollTop){
$(".smart-scroll").removeClass("scrolled-up");
} else {
$(".smart-scroll").addClass("scrolled-up");
}
lastScrollTop = st;
});
}
And CSS
.smart-scroll {
position: fixed !important;
top: 0;
right: 0;
left: 0;
z-index: 1000;
transition: all 0.3s ease-in-out;
transform:translateY(0);
}
.stick {transform:translateY(-100%);}
.scrolled-up {transform:translateY(0) !important;}
I added this below the if/else statement to prevent from hiding at the very top
if(scroll_top <= 0) {
$('.headerContainer').removeClass('scrolled-up').removeClass('scrolled-down');
}
Related
I'm using this code to make my sticky navbar disappear on scroll down and re-appear on scroll up. However this code is pretty precise resulting sometimes in starting one of both animations without actually scrolling.
What I'm trying to achieve is that a user should scroll 20px down before the if statement runs. Same if they would scroll up again...
https://jsfiddle.net/as1tpbjw/2/
const body = document.querySelector("#navbar");;
let lastScroll = 0;
window.addEventListener("scroll", () => {
const currentScroll = window.pageYOffset;
if (currentScroll <= 0) {
body.classList.remove("scroll-up");
return;
}
if (currentScroll > lastScroll && !body.classList.contains("scroll-down")) {
body.classList.remove("scroll-up");
body.classList.add("scroll-down");
} else if (
currentScroll < lastScroll &&
body.classList.contains("scroll-down")
) {
body.classList.remove("scroll-down");
body.classList.add("scroll-up");
}
lastScroll = currentScroll;
});
As far as I can see, in my relatively old version of Firefox, it works well.
I added if (Math.abs(currentScroll - lastScroll) < 20) { return; } and this adds a 20px delay either way.
Also, that scroll-up class doesn't seem to be doing anything in the fiddle.
Update:
If you want an animation, you can replace the CSS for .scroll-down and add a transition to #navbar:
#navbar.scroll-down {
height: 0;
}
#navbar {
/* … */
transition: height .5s;
}
Not only does scroll-up do nothing, but the following code even breaks (doesn't show the navbar) when you scroll to the top:
if (currentScroll <= 0) {
body.classList.remove("scroll-up");
return;
}
You may want to remove it.
const body = document.querySelector("#navbar");
let lastScroll = 0;
window.addEventListener("scroll", () => {
const currentScroll = window.pageYOffset;
if (Math.abs(currentScroll - lastScroll) < 20) {
return;
}
if (currentScroll > lastScroll) {
body.classList.add("scroll-down");
} else {
body.classList.remove("scroll-down");
}
lastScroll = currentScroll;
});
body {
margin: 0;
min-height: 200vh;
}
#navbar.scroll-down {
height: 0;
}
#navbar {
height: 50px;
background: red;
position: sticky;
top: 0;
left: 0;
transition: height .5s;
}
<body>
<div id="navbar">
</div>
</body>
I am trying to make nice parallax website, but this is my first time when I am using jQuery, however I have the following problem:
HTML:
<div class="section4"><h1 class="text-center">Online Marketing</h1></div>
<div class="section4"><p style="text-align:justify">SOME TEXT IS HERE BUT IT DOES NOT IMPORTANT</p></div>
CSS:
.section4 {
margin-bottom: 20px;
position: relative;
opacity: 0;
transform: translateX(-40px);
}
.is-showing{
opacity: 1;
transform: translateX(0px);
transition: all 0.3s ease-in-out;
}
.is-hide {
opacity: 0;
position: relative;
}
JS:
var wScroll = $(this).scrollTop();
if($(window).scrollTop() > 800){
if (wScroll > $('.section4').offset().top - ($(window).height() / 2.2)) {
$('.section4').each(function(i){
setTimeout(function(){
$('.section4').eq(i).addClass('is-showing');
}, 250 * (i+1));
})
}
}
So when I am scrolling down it is work great. It fades in properly, but now I want, when user scroll up, to it disappears. I tried with:
JS :
else {
$('.section4').eq().addClass('is-hide');
})
//$('section4').fadeOut("slow");
}
/*if (wScroll < $('.section4').offset().top + ($(window).height() - 500)) {
$('.section4').addClass('is-hide');
}*/
And lot of simular example, but now I don't have idea how to fix it, so if someone can give me advice or some solution I will appreciate it.
If I wanted to detect scroll direction,, I would do the following:
var lastScrollTop = 0;
var isScrollingDown = false;
$(window).scroll(function (event) {
var currentScrollTop = $(window).scrollTop();
if (lastScrollTop > currentScrollTop ) {
isScrollingDown = false;
} else {
isScrollingDown = true;
}
// Do something
});
You can use this logic within your code to do as required.
In case you are looking third party solution you can check out Wow.js
It is great lightweight library that uses animate.css effects on scrolling.
I have included a snippet to show the general idea of what I have right now. The snippet will show a header and if you scroll the header stays the same size until the full height of the header has been scrolled down and then it will go away. Then when you scroll up (when the header gone) the header will show.
The issue I cannot seem to figure out is how to remove the position: fixed from my css and still get the javascript to work. I want the header to scroll down normally (just like Stack overflow's header), however with the ability to still re-appear when scrolling up.
I tried taking out position: fixed and the script broke. I also tried adding position: fixed to the nav-up class...neither change worked.
Does anyone know what I could do to make this work?
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;
}
html, body {
padding:0;
margin:0;
}
header {
/*background: #2F4F4F;*/
/*background: #53868B;*/
/*background: #35586C;*/
background: #F2F2F2;
height: 120px;
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
z-index: 100;
}
.nav-up {
top: -120px;
}
#logo {
padding: 5px 20%;
display: inline-block;
}
#logo img {
height: 110px;
width: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<header class="nav-down">
<div id="logo">
<img src="images/eslich.png" alt="">
</div>
</header>
<br><br><Br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><Br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><Br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><Br><br><br><br><br><br><br><br><br><br><br><br><br>
Update
This is the new jsfiddle using her code https://jsfiddle.net/jz8aa5yz/2/
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 {
if (st < navbarHeight) {
if (st === 0 || st < 50) {
$('header').css('position', 'static');
}
} else {
$('header').css('position', 'fixed');
}
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('header').removeClass('nav-up').addClass('nav-down');
}
}
lastScrollTop = st;
}
`
Old
I'm still testing some javascript, but I wonder if the effect you wanted is something like this? I did a few things different, but the main things were using hide(), css(), slideUp(), slideDown(), and if / else statements. Here's a jsfiddle of the example
<script>
$(document).ready(function () {
var header = $("header");
var lastScrollTop = 0;
$(window).on("scroll", function () {
currentScrollTop = $(this).scrollTop();
if ($("body").scrollTop() > header.outerHeight()) {
if (currentScrollTop > lastScrollTop) {
if (header.css("position") == "fixed") {
header.slideUp();
} else {
header.css({
display: "none",
position: "fixed"
});
}
} else {
header.slideDown();
}
} else {
if (currentScrollTop === 0) {
header.css({
display: "block",
position: "static"
});
}
}
lastScrollTop = currentScrollTop;
});
});
</script>
I made this snippet code to hide menu on scroll down and show on scroll up but I have some issues, when I scroll to top the menu still have fixed position, how I can resolve this problem, Thanks!
JAVSCRIPT :
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
});
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('.mainmenu').outerHeight();
$(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 500);
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
$('.mainmenu').removeClass('nav-down').addClass('nav-up');
} else {
// Scroll Up
if(st + $(window).height() < $(document).height()) {
$('.mainmenu').removeClass('nav-up');
}
}
lastScrollTop = st;
}
CSS :
.mainmenu {
background: #222;
height: 50px;
padding: 0 15px;
width: 80%;
margin: 0 auto;
}
.nav-down{
position: fixed;
top: 0;
transition: top 0.2s ease-in-out;
width: 100%;
}
.nav-up {
top: -50px;
}
Demo : jsfiddle
To you first listener, just add an else statement as follows:
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 150)
$('.mainmenu').addClass('nav-down');
else
$('.mainmenu').removeClass('nav-down');
});
Also note that you don't need a setInterval() for the second listener, see jsfiddle
I tested it and it works fine!!
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
else
{
$('.mainmenu').removeClass('nav-down');
}
});
Add an else to your scrollTop with a removeClass and you should be fine, I tested it and it works. Here
$(window).bind('scroll', function () {
if ($(window).scrollTop() > 500) {
$('.mainmenu').addClass('nav-down');
}
else
{
$('.mainmenu').removeClass('nav-down');
}
});
Detect nav direction with a variable
var lastscrolltop=0;
jQuery(window).bind('scroll', function () {
if (jQuery(window).scrollTop() > lastscrolltop)
jQuery('.mainmenu').addClass('nav-up');
else
jQuery('.mainmenu').removeClass('nav-up');
lastscrolltop=jQuery(window).scrollTop();
});
and use css transition for a smooth show/hide
.mainmenu {
transition:all 0.5s ;
}
Your way is too much complicated.
You can hide the menu on scroll with a simple transition using jQuery .fadeIn() and fadeOut(), without the need for css.
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
$('.mainmenu').fadeOut('fast');
} else {
$('.mainmenu').fadeIn('fast');
}
lastScrollTop = st;
});
I have this simple navigation that was built to hide a fixed header when scrolling down. When you scroll up it will reappear for easy navigation. It works great! However, I need it changed up a bit and not sure how to accomplish this.
When the position is fixed at the absolute top of the page I need the header to be transparent. When the position is then scrolled down and then scrolled up a little. I need the background to be blue until it reaches the absolute top then again change to transparent.
http://codepen.io/anon/pen/VYPGyg
here is the jQuery in question:
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;
}
Any help would be great!
I would use your nav-down and nav-up classes, since they're getting added anyways. When you use CSS to handle styling, you're (usually) better separating concerns amongst various aspects of your software. CSS should usually handle presentation, except where it's functionality is limited or not programmatic enough (enter javascript).
For example, take your .nav-down class and adjust the transparency:
Updated codepen:
http://codepen.io/anon/pen/YPNOLM
Added some logic to your function:
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');
}
// the 100 can be whatever height you think it should be at
if($(window).scrollTop() > 100) {
$('header').addClass('notTop')
} else {
$('header').removeClass('notTop')
}
}
lastScrollTop = st;
}
And an opacity property:
header.nav-down {
position: fixed;
width: 100%;
top: 0;
transition: top 0.2s ease-in-out;
z-index: 1;
background: #fff;
padding: 25px 0px 0px 0px;
opacity: 0.8
}
And:
header.nav-down.notTop {
background-color: blue
}