Make .removeClass() and .addClass() transition smoothly on scoll up and down - javascript

I am trying to transfer between display:none, and display:block. The div with the id #octopus-head is supposed to fade out when scrolling down, and back in when scrolling up, but right now it just pops in or out instantly.
Here is the javascript I am working with:
//sticky header scripts
// Hide Header on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = jQuery('.scroll-height-setter').innerHeight();
jQuery(window).scroll(function(event){
didScroll = true;
});
setInterval(function() {
if (didScroll) {
hasScrolled();
didScroll = false;
}
}, 100);
function hasScrolled() {
var st = jQuery(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
jQuery('#octopus-head').removeClass('nav-down').addClass('nav-up').fadeOut(1000);
} else {
// Scroll Up
if(st + jQuery(window).height() < jQuery(document).height()) {
jQuery('#octopus-head').removeClass('nav-up').addClass('nav-down').fadeIn(1000);
}
}
lastScrollTop = st;
}

Display none cannot use transitions as there is nothing to transition from.
You could use setTimeout() to add a transition class that renders the div with opacity of zero and then switch classes to your final opacity 100%.
Or you could just always use opacity and never display none the div. It depends on what you actually need.

Related

Detect scroll up when your top of page

Im using a script to detect scroll up to click a previous link. I want to detect scroll up even when your top of the page and do a scroll up. Now I have to scroll down a bit then up again. How can I do this?
Code:
var lastScrollTop = 0, delta = 5;
jQuery(window).scroll(function(){
var nowScrollTop = jQuery(this).scrollTop();
if(Math.abs(lastScrollTop - nowScrollTop) >= delta){
if (nowScrollTop > lastScrollTop){
// ACTION ON
// SCROLLING DOWN
} else {
jQuery( 'a.action.previous' ).click ();
}
lastScrollTop = nowScrollTop;
}
});

trying to achieve some effect on the background when page scrolling

I'm trying to achieve this effect here in the header, that make the background go up and down when scrolling
here is the example
https://frix.themes95.com/
here what I've tried
https://stackblitz.com/edit/angular-ivy-yzx998?file=src%2Fapp%2Fapp.component.ts
it almost does the required but there is something goes wrong when I'm trying to scroll up
You're forgetting to set your lastScrollTop variable after each scroll event, so it always thinks you're scrolling down. Just put this.lastScrollTop = st; as your last line in the onScroll function like this:
onScroll(event) {
const st = window.pageYOffset || document.documentElement.scrollTop;
if (st > this.lastScrollTop) {
this.pxToMove -= 3;
this.background.nativeElement.style.transform = `translateY(${this.pxToMove}px)`;
} else {
this.pxToMove += 3;
this.background.nativeElement.style.transform = `translateY(${this.pxToMove}px)`;
}
this.lastScrollTop = st;
}
Here's a way to condense this function and have it change position based on how far you've scrolled.
onScroll(event) {
const st = window.pageYOffset || document.documentElement.scrollTop;
// Move the image by the difference between the old and new scrollTop
this.pxToMove -= (st-this.lastScrollTop);
this.background.nativeElement.style.transform = `translateY(${this.pxToMove}px)`;
// Set the previous scrollTop
this.lastScrollTop = st;
}

Wondering whats in this script causing it not to work in the new jquery update

Here is a link to a fiddle I was looking at which does exactly what i'm looking for:
https://jsfiddle.net/mariusc23/s6mLJ/31/
Upon attempting to apply this for my own purposes I realized that it was not working at all. I came to the conclusion that it was the version I was using causing it not to work..
Not really a javascript/ jquery buff so I was wondering what precisely in this script causing it to not work with jquery 3.0.0-rc1 but instead with the older version jquery 1.10.2
// 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;
}

Waypoints JS Move Main Menu to Fixed Header on Scroll Up

I have a main header (#top-bar) with page navigation and a sub-navigation bar (#category-bar) with links to sections on the page. The sub-navigation bar loads on the bottom of the screen, then as the user scrolls down the sub-navigation bar pushes the fixed position main header off screen by changing it to absolute position. The sub-navigation bar becomes fixed to the top. This all works fine with waypoints js triggering different position states for the bars.
I now need to have the main header reappear on scroll up. Here is my javascript so far, though it does not effect the header on scroll up:
function moveHeader() {
var topBar = '#top-bar',
var stickyElement = jQuery('#category-bar');
var bottomBarOffset = stickyElement.offset();
var topOffset = jQuery(topBar).offset().top; //get the offset top of the element
jQuery(stickyElement).waypoint({
handler: function(direction) {
if (direction === 'down') {
jQuery(topBar).css({ position: 'absolute', top: bottomBarOffset.top - jQuery(topBar).outerHeight() });
}
else {
jQuery(topBar).attr('style', '');
}
},
offset: topBarHeight - 1,
});
jQuery(topBar).waypoint({
handler: function(direction) {
if (direction === 'up') {
jQuery(this.element).addClass('pin');
}
else {
jQuery(this.element).removeClass('pin');
}
},
offset: topOffset - jQuery(window).scrollTop() - 100, //attempt to trigger main header pushed off screen top
});
}
I have tried different calculations to trigger the #top-bar without any luck. Does anyone have advice for the calculation or different approach for this project?
After reading more related SO topics and some tests with waypoints js, I abandoned waypoints js for this portion of the script. I created a function for calculating the trigger point for setting the fixed header. The variable calculation constantly changed on scroll up, which caused waypoints to continually fire and create a flickering effect. This made me realize that this implementation is not the proper use for waypoints. My solution implements a simple scroll up / scroll down jQuery function after leaving the top section. In this script, it is set to fire on a 20 pixel scroll in either direction:
function moveHeader() {
var topBar = '#top-bar',
var stickyElement = '#category-bar';
var bottomBarOffset = jQuery(stickyElement).offset();
var topBarOffset = jQuery(topBar).offset().top;
jQuery(stickyElement).waypoint({
handler: function(direction) {
if (direction === 'down') {
jQuery(topBar).css({ position: 'absolute', top: bottomBarOffset.top - jQuery(topBar).outerHeight() });
}
else {
jQuery(topBar).attr('style', '');
}
},
offset: topBarHeight - 1,
});
jQuery(function(){
var lastScrollTop = 0;
var scrollDistance = 20;
if (jQuery('body').hasClass('page-template-page-sections-menu')) {
jQuery(window).scroll(function(event){
var st = jQuery(this).scrollTop();
if(Math.abs(lastScrollTop - st) <= scrollDistance)
return;
if (st > lastScrollTop && st > windowHeight && jQuery('body').hasClass('scroll-up'))
{
// downscroll code
jQuery('body').addClass('scroll-dn');
jQuery('body').removeClass('scroll-up');
jQuery(stickyElement).attr('style', '');
} else if (st < lastScrollTop && st > windowHeight)
{
// upscroll code
jQuery('body').addClass('scroll-up');
jQuery('body').removeClass('scroll-dn');
jQuery(topBar).attr('style', '');
jQuery(stickyElement).attr('style', '');
} else if (st < lastScrollTop && st < windowMinusTop)
{
// upscroll and first section (window height from top of document)
jQuery(stickyElement).css({ 'z-index': '0' });
jQuery('body').removeClass('scroll-up scroll-dn');
}
lastScrollTop = st;
});
};
});
}
This solution achieves what my client needs, though I am open to any further improvements.

Display div when at bottom of page

Right now i have made the footer to appear when i scroll up and hide when i scroll down.
How do i make it appear when i am at the bottom of page?
https://jsfiddle.net/48az3u64/
// Hide Footer on on scroll down
var didScroll;
var lastScrollTop = 0;
var delta = 5;
var navbarHeight = $('footer').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 (st > lastScrollTop && st > navbarHeight){
$('footer').removeClass('nav-up').addClass('nav-down');
} else {
if(st + $(window).height() < $(document).height()) {
$('footer').removeClass('nav-down').addClass('nav-up');
}
}
lastScrollTop = st;
}
See this fiddle https://jsfiddle.net/48az3u64/9/
I only added a function IsBottom() found from this post How do you know the scroll bar has reached bottom of a page
function IsBottom() {
return $(window).scrollTop() == ($(document).height() - $(window).height());
}
to add your nav-up class back when you scroll, and to disable your timer.
I strongly suggest not to use a timer for this kind of thing, since you are processing your function every quarter of seconds even if there haven't been any scroll. You should probably just call your hasScrolled() directly in the scroll event and use a debounce function to not fire it too much. Here is a link for more info on debounce
http://davidwalsh.name/javascript-debounce-function

Categories

Resources