Sticky header jumps on fast scrolling - javascript

I have problem with sticky header. I have placeholder to keep good height when i am scrolling and it's working fine. Problem appear when i scroll faster. I read that jquery scroll position by 1-2-4-12.. pixels at once and by it my sticky header stick not on position i wanted what couse something like jump or blink.
scroll() {
let queryWindow = Ember.$(window);
let siteBarHeight = Ember.$('.folded').offset() ? 19 : 47;
queryWindow.scroll(() => {
let fixedHeader = this.get('fixedHeader');
let shouldBeFixed = queryWindow.scrollTop() > 90 + siteBarHeight;
if (!fixedHeader && shouldBeFixed) {
this.set('fixedHeader', true);
} else if (fixedHeader && !shouldBeFixed) {
this.set('fixedHeader', false);
}
});
}
This all working fine when my scroll slowly, but in other way jquery stick it too late. Thanks in advance for helping me, tell me if you need more information about it.

Related

jQuery Navbar transition on scroll. How to adjust specific point of transition

In a site I'm building I'm trying to make the navbar change color when I scroll. However, I don't want it to change colors as soon as I start scrolling. I want it at a specified point (once I scroll past my jumbotron).
So far, I've only been able to make it work by scrolling from the top. I'm not quite skilled enough to figure out how to do it past a specific point on my page. I would greatly appreciate some guidance on this.
jQuery script
$(function () {
$(document).scroll(function () {
var $nav = $(".fixed-top");
$nav.toggleClass('scrolled', $(this).scrollTop() > $nav.height());
});
});
Thanks for any help or guidance!
There are a lot of ways you can do it.
one way could be done with pure javascript.
change changeColorValue that represents the scroll bar value according to your needs.
Here is my suggestion:
LIVE DEMO
JavaScript:
var changeColorValue = 50;
window.addEventListener("scroll", scrollAnim);
function scrollAnim () {
var val = getScrollVal();
if(val > changeColorValue)
{
document.getElementById('mynav').style.backgroundColor = 'red';
}
else
{
document.getElementById('mynav').style.backgroundColor = '#333';
}
}
function getScrollVal()
{
var val = $(document).scrollTop();
return val;
}

How to make a navigation sticky when it reached to another top nav

I have two navigation one is on the top and another is in content. I try to make the second sub menu as sticky when it reached to the top menu not the very top offset of browser. But i failed to make it sticky when it scrolled to top. Also how can I add class on on menu item when active 'href' scrolling.
JSfiddle Here
JS Code
$(document).ready(function() {
var $filter = $('.denpen-menu');
var $filterSpacer = $('<div />', {
"class": "filter-drop-spacer",
"height": $filter.outerHeight()
});
if ($filter.size())
{
$(window).scroll(function ()
{
if (!$filter.hasClass('navbar-fixed') && $(window).scrollTop() > $filter.offset().top)
{
$filter.before($filterSpacer);
$filter.addClass("navbar-fixed");
}
else if ($filter.hasClass('navbar-fixed') && $(window).scrollTop() < $filterSpacer.offset().top)
{
$filter.removeClass("navbar-fixed");
$filterSpacer.remove();
}
});
}
});
First we should fetch the starting position of our subNavand store it as "startingPoint"
var startingPoint = $('.stuckMenu').offset().top - 48;
Notice the - 48 part, that's about the height of our main navigation, and a bit less just so it feels better when they touch.
The key part of the logic is this part here:
if (!subNav.hasClass('navbar-fixed') && $(window).scrollTop() > startingPoint)
{
$filter.addClass("navbar-fixed");
}
else if(subNav.hasClass('navbar-fixed') && $(window).scrollTop() < startingPoint)
{
$filter.removeClass("navbar-fixed");
}
Where we ask:
Is our subNav sticky yet? Is the top of the window touching it currently?
Ok its not sticky yet but the window touched it, make it sticky - fixed.
Ok so our subNav is sticky, is the top of the window above the original position of our subNav?
It is above? Ok I do not want it to be sticky any more, so we'll just remove the class.
Check out the example here

How do I recalculate the section's height on scroll for a fixed navigation that changes class past certain anchors?

Context
I am working on a one-page website where the fixed navigation's class changes as it scrolls through the different sections in order to match the section's background color. To achieve this effect, I used and modified the 2nd solution listed here.
Issue
While it works great most of the time, the navigation code breaks when I resize the browser (or leave the page and click back). More specifically, the navigation's background color changes too early or too late and no longer matches the section's background.
I'm guessing that this happens because the section's height are calculated on page load. Ideally, they would be recalculated on every scroll - but I am a novice and that's just a guess. Any help to solve this issue would be appreciated.
JavaScript
FYI: there are four sections in the websites (Hero, Work, About, Contact). Navigation's bg color should be transparent in Hero, white in Work and Contact, and teal in About.
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
$(window).on('scroll', function() {
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Just try adding all your size variables into your scroll event handler:
$(window).on('scroll', function() {
var afterhero = $('#hero-section').offset().top + $('#hero-section').height();
var afterwork = afterhero + $('#work-section').height();
var afterabout = afterwebsites + $('#about-section').height();
stop = Math.round($(window).scrollTop());
if (stop > afterabout) {
$('header').removeClass('teal');
$('header').addClass('white');
} else if (stop > afterwork) {
$('header').addClass('teal');
} else if (stop > afterhero) {
$('header').removeClass('teal');
$('header').addClass('white');
} else {
$('header').removeClass('teal');
$('header').removeClass('white');
}
});
Now afterhero, afterwork and afterabout should all be recalculated on a page scroll.

How do I add a class to the body using jQuery, scrollTop, and toggleClass

I have a question concerning jQuery's scrollTop functionality, and it's ability to toggle a class based on the amount of vertical scroll.
What I am trying to accomplish is on any page with a "section.banner" class, that after you scroll past the banner a class is applied to the body tag. This will allow me to change the fill colors of several SVGs that are in the site's header, as well as a fixed positioned side nav that is for pagination.
I am terrible at javascript, and have been stuck searching and trying to get this for hours. any help will be greatly appreciated. Here's the code that I'm working with now (CodeKit is telling me it is wrong, which I am not surprised). The value of 200 is just a placeholder and will be calculated by the height of a fluid image. Full disclosure, I have no idea if the brackets and parenthesis are correct.
// Header/Fixed Pagination Banner Scroll Recoloriing (toggle class)
// Check If '.banner' Exists
if( $('section.banner').length > 0) {
$('body').scrollTop(function)()
{
if $(window).scrollTop >= 200 {
$('body').toggleClass('downtown');
return false;
}
}
}
Try something like this :
if( $('section.banner').length > 0) {
$(window).scroll(function() {
{
if ($(window).scrollTop() >= $('section.banner').scrollTop()) {
$('body').toggleClass('downtown');
return false;
}
});
}
UPDATE
There was little mistake in my code : http://jsfiddle.net/t2yp15hq/
var top = $('section.banner').position().top;
if($('section.banner').length > 0) {
$(window).scroll(function() {
if ($(this).scrollTop() >= top) {
$('body').addClass('downtown');
}
else
{
$('body').removeClass('downtown');
}
});
}
It does not work with toogleClass, the background is flashing.
UPDATE
http://codepen.io/anon/pen/wBWzXy
The solution is to recalculate the top when the window is resized :
$(window).resize(function(){
top = $('section.story-intro').offset().top - 90;
});

Get divs within viewport inside a wrapper div

Is there a way to get elements which is:
Inside a div with overflow: scroll
Is in viewport
Just like the following picture, where active div (5,6,7,8,9) is orange, and the others is green (1-4 and >10) :
I just want the mousewheel event to add "active" class to div 5,6,7,8,9 (currently in viewport). View my JSFiddle
$('.wrapper').bind('mousewheel', function (e) {
//addClass 'active' here
});
You could do something like this. I would have re-factored it, but only to show the concept.
Firstly I would attach this to scroll event and not mousewheel. There are those among us that likes to use keyboard for scrolling, and you also have the case of dragging the scrollbar. ;) You also have the case of touch devices.
Note that with this I have set overflow:auto; on wrapper, thus no bottom scroll-bar.
With bottom scrollbar you would either have to live with it becoming tagged as in-view a tad to early, or tumble into the world of doing a cross-browser calculating of IE's clientHeight. But the code should hopefully be OK as a starter.
»»Fiddle««
function isView(wrp, elm)
{
var wrpH = $(wrp).height(),
elmH = $(elm).height(),
elmT = $(elm).offset().top;
return elmT >= 0 &&
elmT + elmH < wrpH;
}
$('.wrapper').bind('scroll', function (e) {
$('div.box').each(function(i, e) {
if (isView(".wrapper", this)) {
$(this).addClass('active');
} else {
$(this).removeClass('active');
}
});
});
Note that you should likely refactor in such a way that .wrapper height is only retrieved once per invocation, or if it is static, at page load etc.
Update; a modified version of isView(). Taking position of container into account. This time looking at dolphins in the pool.
»»Fiddle««
function isView(pool, dolphin) {
var poolT = pool.offset().top,
poolH = pool.height(),
dolpH = dolphin.height(),
dolpT = dolphin.offset().top - poolT;
return dolpT >= 0 && dolpT + dolpH <= poolH;
}

Categories