如何使用 javascript 获取页面中的当前 Viewable 元素?

How to get the current Viewable elements in a page using javascript?

我正在制作一个 nextjs 应用程序, 我想根据视口中的可见部分更改导航栏活动按钮 页面子项看起来像这样

<div id="section1" > </div>
<div id="section2" > </div>
...
<div id="faq" > </div>
<div id="contact" > </div>

例如,当用户滚动并且屏幕中的当前 div 是联系表时 我将其设置为 /#contact 我的主要问题是如何检测视口中的当前可视元素

我怎样才能做到这一点?

您可以使用 Intersection Observer. Here 是一个现场演示,其中 header 上的列表项会在您滚动每个部分时自动突出显示。

Javascript:

// simple function to use for callback in the intersection observer
const changeNav = (entries, observer) => {
    entries.forEach((entry) => {
        // verify the element is intersecting
        if(entry.isIntersecting && entry.intersectionRatio >= 0.55) {
            // remove old active class
            document.querySelector('.active').classList.remove('active');
            // get id of the intersecting section
            var id = entry.target.getAttribute('id');
            // find matching link & add appropriate class
            var newLink = document.querySelector(`[href="#${id}"]`).classList.add('active');
        }
    });
}

// init the observer
const options = {
    threshold: 0.55
}

const observer = new IntersectionObserver(changeNav, options);

// target the elements to be observed
const sections = document.querySelectorAll('section');
sections.forEach((section) => {
    observer.observe(section);
});

HTML:

nav
    ul
        li
            a(href='#one').active One
        li
            a(href='#two') Two
        li
            a(href='#three') Three
        li
            a(href='#four') Four
        li
            a(href='#five') Five
            
section#one
    p Slide One

section#two
    p Slide Two

section#three
    p Slide Three
    
section#four
    p Slide Four
    
section#five
    p Slide Five

CSS:

nav
    position fixed
    
    width 100%
    top 0
    left 0
    right 0
    
    background-color white
    
    ul
        list-style-type none
        display flex
        align-items center
        justify-content space-around
        
        width 100%
        max-width 800px
        height 50px
        
        margin 0 auto
        padding 0
        
    li
        display inline-block

        padding 5px
        
    a
        display block

        height 40px
        
        padding 0 20px
        
        line-height 40px
        text-decoration none
        text-transform uppercase
        color #323232
        font-weight bold
        
        border-radius 4px
        
        transition background-color 0.3s ease-in
        
        &:hover
        &:active
        &:focus
            background-color rgba(#B8D6A8, 0.5)
        
        &.active
            background-color rgba(#B8D6A8, 0.5)
        
        
section
    display flex
    align-items center
    justify-content center
    
    min-height 100vh
    
p
    text-align center
    color white
    font-size 3.5em
    font-weight bold
    text-transform uppercase
    
#one
    background-color #6CA392
    
#two
    background-color #FFA58C
    
#three
    background-color #FF4F30
    
#four
    background-color #576B51
    
#five
    background-color #392A1B