PLC PLC - 2 months ago 7
Javascript Question

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');
}
});

Answer

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.

Comments