Change navigation active class on window scroll

前端 未结 5 1385
心在旅途
心在旅途 2020-12-28 11:31

i want to create a scroll effect like here http://www.strikingly.com/s/pages/default-ion?demo=ion#1 All i need for this moment is to change navigation li class active when

相关标签:
5条回答
  • 2020-12-28 12:10

    hiccup in IE9 so I corrected

    $(document).ready(function () {
        $(document).on("scroll", onScroll);
    
        //smoothscroll
        $('a[href^="#"]').click(function(){
        var target = $(this).attr('href');
        $('html, body').animate({scrollTop: $(target).offset().top-48}, 500);
        return false;
    
            $("#menu a").click(function () {
                $("#menu a").removeClass('active');
            })
            $(this).addClass('active');
    
            var target = this.hash,
                menu = target;
            $target = $(target);
            $('html, body').stop().animate({
                'scrollTop': $(target).offset().top-50}, 500, 'swing', function () {
                window.location.hash = target;
                $(document).on("scroll", onScroll);
            });
        });
    });
    
    function onScroll(event){
        var scrollPos = $(document).scrollTop();
        j$('#menu a').each(function () {
            var currLink = $(this);
            var refElement = $(currLink.attr("href"));
            if (refElement.position().top-70 <= scrollPos && refElement.position().top-50 + refElement.height() > scrollPos) {
               $('#menu ul li a').removeClass("active");
                currLink.addClass("active");
            }
            else{
                currLink.removeClass("active");
            }
        });
    }
    
    0 讨论(0)
  • 2020-12-28 12:11

    DEMO

    Serlite's code is very good but had some bugs.

    1. If you scroll down to the end last two a elements have active class so both are highlighted.

    Solution

    added $('#menu-center ul li a').removeClass("active"); to remove all previous active class before adding new class in the below code.

    function onScroll(event){
        var scrollPos = $(document).scrollTop();
        $('#menu-center a').each(function () {
            var currLink = $(this);
            var refElement = $(currLink.attr("href"));
            if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
                $('#menu-center ul li a').removeClass("active"); //added to remove active class from all a elements
                currLink.addClass("active");
            }
            else{
                currLink.removeClass("active");
            }
        });
    }
    
    1. If you click on 2nd or greater menu link it makes you scroll to the location but changes active class to previous link.

    Solution

    $('html, body').stop().animate({
                'scrollTop': $target.offset().top+2
    
    0 讨论(0)
  • 2020-12-28 12:16

    I know I am late, but my answer may help the new viewers of this thread. Tushar Gupta's answer is correct. But if there a link in menu that is redirecting to any other page. Tushar Gupta's Answer will throw an error. For Example

        <div class="m1 menu">
        <div id="menu-center">
            <ul>
                <li><a  href="#home">Home</a>
                </li>
                <li><a  href="#portfolio">Portfolio</a>
                </li>
                <li><a  href="#about">About</a>
                </li>
                <li><a  href="http://mywebsite.com/blog">Blog</a>
                </li>
                <li><a  href="#contact">Contact</a>
                </li>
            </ul>
        </div>
       </div>
       <div id="home"></div>
       <div id="portfolio"></div>
       <div id="about"></div>
       <div id="contact"></div>
    

    This will throw an error in console like this. And scrolling will not work for Contact. I Updated Tushar's code to fix that issue.

    function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#menu-center a[href*=#]:not([href=#])').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
            $('#menu-center ul li a').removeClass("active"); //added to remove active class from all a elements
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
    });
    }
    
    0 讨论(0)
  • 2020-12-28 12:21

    Use $(this).scrollTop(); on your event listener to check what section is in the viewport.

    0 讨论(0)
  • 2020-12-28 12:26

    Well...not sure if you're still looking for an answer to your question, but I can contribute a suggestion...

    As mentioned, you could use the scrollTop() method to determine what section is presently in the viewport. Here's a quick function I threw together to determine this, it may not be optimized (I'm not a jQuery expert, sorry), but it seems to work, and should at least put you on the right path to a solution:

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

    This function basically takes the href of each menu anchor element, and uses it to find the <div> (or any other element, if you like) with a matching id in the document. After this, it checks to see whether the top of that <div> is above or at the current scroll position, and its bottom is still below the current scroll position. (Those two conditions being true means that this <div> is the one currently highest in the viewport, and so should be considered the active section.) The class .active is then removed/added accordingly. Of course, you can just add/subtract values if you want to offset when a section is considered "active".

    Maybe it's easier just showing what it does, so here's an updated JSFiddle with this function implemented. It's initially bound using $(document).on("scroll") - however, note that I also unbound it from the scroll event using $(document).off("scroll") while the smooth scrolling occurs, so that the section doesn't change until you've reached the destination section (if you click on one of the menu links). After the smooth scrolling occurs, I bind the function again to the scroll event.

    Anyways, I hope this is what you were looking for! If it's not, let me know and I'll be happy to help further. (Or I'll try, at least - since as I mentioned, jQuery isn't really my specialty...) Good luck!

    0 讨论(0)
提交回复
热议问题