Rob Morris
Rob Morris

Reputation: 533

Active class on sticky nav

My sticky nav:

<nav id="page-nav" class="page-nav">
    <ul>    
        <li><a href="#top" class="linky active">Overview</a></li>
        <li><a class="linky" href="#sub-our-drainage-solutions">Our drainage solutions</a></li>
        <li><a class="linky" href="#sub-cctv-drain-survey">CCTV drain survey</a></li>
        <li><a class="linky" href="#sub-wet-waste-disposal">Wet waste disposal</a></li>
        <li><a class="linky" href="#sub-blocked-drains">Blocked drains</a></li>
        <li><a class="linky" href="#sub-cess-pit-emptying">Cess pit emptying</a></li>
    </ul>
</nav>

<div id="sub-our-drainage-solutions">

</div>

<div id="sub-cctv-drain-survey">

</div>

etc...

$(function() {
    //sticky scroll to nav
    //page nav
    var s = $("#page-nav"),
        //sectorContent = $("#sector-content"),
        pos = s.position(), 
        linkClicked = false,
        w = $(window).width();

      if(w > 800) {

        $(window).scroll(function() {
            var windowpos = $(window).scrollTop();
            if (windowpos >= pos.top) {
                s.addClass("stick");
            } else {
                s.removeClass("stick"); 
            }
        });

        $(window).scroll(function() {
            var y = $(this).scrollTop();
            $('.linky').each(function(event) {
                id = $(this).attr('href');
                if (y >= $(id).offset().top -30) {
                    if (!linkClicked) { 
                        $('.linky').not(this).removeClass('active');
                        $(this).addClass('active');
                    }
                }
            });

        });

        $("#page-nav li a").click(function(e) { 
            e.preventDefault();
            $("#page-nav li a").removeClass('active');
            $(this).addClass('active');
            linkClicked = true; 
            goToByScroll($(this).attr("href").replace("#", ""));           
        });

        function goToByScroll(id){
            $('html,body').animate({
                scrollTop: $("#"+id).offset().top -30},
                 'slow', function() {
                     linkClicked = false;
                });
        }

    }
});

The navigation sticks to the top of the window on scroll, I also need it to change active class on the anchor when it passes the related div id.

I'm getting the following error on scroll:

Uncaught TypeError: Cannot read property 'top' of null

due to this part of the code:

$(window).scroll(function() {
            var y = $(this).scrollTop();
            $('.linky').each(function(event) {
                id = $(this).attr('href');
                if (y >= $(id).offset().top -30) {
                    if (!linkClicked) { 
                        $('.linky').not(this).removeClass('active');
                        $(this).addClass('active');
                    }
                }
            });

        });

What can I do to resolve this issue?

Upvotes: 0

Views: 474

Answers (1)

fatzak
fatzak

Reputation: 11

Not sure what is happening with your code, but this snippet works well for me to change the active class on scroll and smooth scrolling to go with.

$(document).ready(function () {
    $(document).on("scroll", onScroll);
    
    //smoothscroll
    $('#nav-minor a[href^="#"]').on('click', function (e) {
        e.preventDefault();
        $(document).off("scroll");
        
        $('#nav-minor a').each(function () {
            $(this).removeClass('active');
        })
        $(this).addClass('active');
      
        var target = this.hash,
            menu = target;
        var $target = $(target);
        $('html, body').stop().animate({
            'scrollTop': $target.offset().top+2
        }, 500, 'swing', function () {
            window.location.hash = target;
            $(document).on("scroll", onScroll);
        });
    });
});

function onScroll(event){
    var scrollPo = $(document).scrollTop();
    $('#nav-minor a').each(function () {    
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPo && refElement.position().top + refElement.height() > scrollPo) {
            $('#nav-minor a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }

    });
}

Then just need some basic css styling of a class="active"

Upvotes: 1

Related Questions