javascript 使用 jQuery 查找当前可见元素并更新导航

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6848269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 22:05:35  来源:igfitidea点击:

Using jQuery to find current visible element and update navigation

javascriptjqueryscrolltovisible

提问by rebz

First time user here. I am usually capable of finding answers for questions but I am having a difficult time figuring this one out.

第一次来这里的用户。我通常能够找到问题的答案,但我很难弄清楚这一点。

The Goal:

目标:

I have a single page layout with a sidebar navigation that when clicked will scroll down to an element on the page. However, if the user just scrolls down the page to a specific element #idI want the corresponding link in the navigation to become .active. The navigation link and the corresponding element share the same value via element#idand a[name].

我有一个带有侧边栏导航的单页面布局,单击时将向下滚动到页面上的一个元素。但是,如果用户只是将页面向下滚动到特定元素,#id我希望导航中的相应链接变为.active. 导航链接和相应的元素通过element#id和共享相同的值a[name]

Similar to:NikeBetterWorld.com

类似于:NikeBetterWorld.com

HTML Example below:

下面的 HTML 示例:

<nav>
    <a name="value">Link</a>
</nav>

<section id="value">
    content goes here
</section>

Obviously, there's more sections, links, elements, etc. But this is the gist of it. So when the user scrolls down to section#valuethe a[value]will have gained the class active.

显然,还有更多的部分、链接、元素等。但这就是它的要点。因此,当用户向下滚动到section#valuea[value]将都获得了积极的类。

I found an answer on here earlier that has helped somewhat but I am still having some issues. See this link for more information.

我之前在这里找到了一个答案,该答案有所帮助,但我仍然遇到一些问题。有关详细信息,请参阅此链接

Current Javascript/jQuery:

当前的 Javascript/jQuery:

$(document).scroll(function() {
    var cutoff = $(window).scrollTop();
    var cutoffRange = cutoff + 200;

    // Find current section and highlight nav menu
    var curSec = $.find('.current');
    var curID = $(curSec).attr('id');
    var curNav = $.find('a[name='+curID+']');
    $(curNav).addClass('active');

    $('.section').each(function(){
        if ($(this).offset().top > cutoff && $(this).offset().top < cutoffRange) {
            $('.section').removeClass('current')
            $(this).addClass('current');
            return false; // stops the iteration after the first one on screen
        }
    });
});

The Problem:

问题:

While the above code works to an extent I am running into one big issue. I am having trouble getting an entire element to stay .current. If the top of the element goes out of the window it will lose the class. I fixed that by adding a range for new elements, but now when the user scrolls upwards the previous element will not gain the class .currentuntil the top of the element reaches the top of the window. I would prefer it if a dominant portion of the window, when visible, gained the .currentclass.

虽然上面的代码在某种程度上有效,但我遇到了一个大问题。我无法保留整个元素.current。如果元素的顶部离开窗口,它将丢失该类。我通过为新元素添加一个范围来解决这个问题,但是现在当用户向上滚动时,前一个元素将不会获得类,.current直到元素的顶部到达窗口的顶部。如果窗口的主要部分在可见时获得.current该类,我会更喜欢它。

Any help, ideas or suggestions would be greatly appreciated.

任何帮助、想法或建议将不胜感激。

Thanks in advance!

提前致谢!

回答by James Montagne

It sounds like you want to check the bottom edge of the section and not the top. Try this and remove the range all together:

听起来您想检查该部分的底部边缘而不是顶部。试试这个并一起删除范围:

if($(this).offset().top + $(this).height() > cutoff){

EDIT: Created a fiddle. I think this is what you're describing.

编辑:创建了一个小提琴。我想这就是你所描述的。

http://jsfiddle.net/pdzTW/

http://jsfiddle.net/pdzTW/

回答by Wan

yeeeahhh! got the solution!

是啊!得到了解决方案!

I just change from:

我只是从:

if ($(window).scrollTop() >= $(section).offset().top) {

to

if ($(window).scrollTop() + 80 >= $(section).offset().top) {

回答by Ben

I always use jQuerys "filter" function to return the current section.

我总是使用 jQuery 的“过滤器”函数来返回当前部分。

$currSection = $('section').filter(function() {
    var $this = $(this);
    var offset = $this.offset().top;
    var view = winHeight / 2;

    return scrollTop >= offset - view && offset + ($this.outerHeight() - view) >= scrollTop;
});

Wrap it in a scroll listener like:

将其包装在滚动侦听器中,例如:

$(window).on('scroll', function() {
    // here we go ...
});

Thats it.

而已。