简体   繁体   English

在窗口滚动上更改导航活动类

[英]Change navigation active class on window scroll

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 the window is scrolling , just change the it using <a href='#about'> hash target 我想在这里创建一个滚动效果http://www.strikingly.com/s/pages/default-ion?demo=ion#1此刻我需要的是在窗口滚动时更改导航li类活动,只需使用<a href='#about'>哈希目标更改它

http://jsfiddle.net/Dxtyu/131/ http://jsfiddle.net/Dxtyu/131/

DEMO DEMO

Serlite 's code is very good but had some bugs. Serlite的代码非常好,但有一些错误。

  1. If you scroll down to the end last two a elements have active class so both are highlighted. 如果您向下滚动到最后两个端a元素都有active类这样既突出。

Solution

added $('#menu-center ul li a').removeClass("active"); 添加$('#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

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. 如上所述,您可以使用scrollTop()方法来确定视口中当前的哪个部分。 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: 这是一个快速的功能,我一起决定这个,它可能没有优化(我不是jQuery专家,对不起),但它似乎工作,至少应该让你走上正确的解决方案的道路:

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. 此函数基本上获取每个菜单锚元素的href ,并使用它来查找文档中具有匹配id的<div> (或任何其他元素,如果您愿意)。 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. 在此之后,它检查该<div>的顶部是在上方还是在当前滚动位置,并且其底部仍然低于当前滚动位置。 (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. (这两个条件为true表示此<div>是视口中当前最高的那个,因此应该被视为活动部分。)然后相应地删除/添加类.active 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. 也许它更容易展示它的作用,所以这里是一个更新的JSFiddle实现了这个功能。 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). 它最初使用绑定$(document).on("scroll") -但是,请注意,我也绑定它使用的滚动事件$(document).off("scroll")而平滑滚动,所以这部分在您到达目的地区域之前不会更改(如果您单击其中一个菜单链接)。 After the smooth scrolling occurs, I bind the function again to the scroll event. 平滑滚动发生后,我再次将该函数绑定到scroll事件。

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! (或者我会尝试,至少 - 因为正如我所提到的,jQuery并不是我的专长......)祝你好运!

Use $(this).scrollTop(); 使用$(this).scrollTop(); on your event listener to check what section is in the viewport. 在您的事件侦听器上检查视口中的哪个部分。

hiccup in IE9 so I corrected 在IE9中打嗝,所以我纠正了

$(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");
        }
    });
}

I know I am late, but my answer may help the new viewers of this thread. 我知道我迟到了,但我的回答可能有助于这个帖子的新观众。 Tushar Gupta's answer is correct. Tushar Gupta的回答是正确的。 But if there a link in menu that is redirecting to any other page. 但是如果菜单中的链接重定向到任何其他页面。 Tushar Gupta's Answer will throw an error. Tushar Gupta的答案会引发错误。 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. 我更新了Tushar的代码来解决这个问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM