【问题标题】:Detect element currently in viewport检测当前在视口中的元素
【发布时间】:2016-12-28 11:42:25
【问题描述】:

我有一个带有固定标题的页面,我试图在导航中获取li 元素,以根据当前滚动点根据用户窗口更改样式。

我的印象是,最好的方法是找出当前位于视口顶部的元素。如果我有 4 个以上的 divspage-section 类,我如何找到当前页面顶部的 id

【问题讨论】:

标签: javascript jquery html css


【解决方案1】:

刚刚重新发现了我的这个问题。

我正在寻找 waypoints js 库。

【讨论】:

    【解决方案2】:

    欢迎来到 SO,

    您可以尝试使用getBoundingClientRect 方法。它将为您提供相对于视口的元素位置。看下一段代码的逻辑,它会给你一个实现工作的线索(重要的部分是checkVisibleSection函数的第一个代码):

    HTML 代码

    <ul id="navigation">
      <li data-section="1"><a class="active" href="#">Section 1</a></li>
      <li data-section="2"><a href="#">Section 2</a></li>
      <li data-section="3"><a href="#">Section 3</a></li>
      <li data-section="4"><a href="#">Section 4</a></li>
      <li data-section="5"><a href="#">Section 5</a></li>
    </ul>
    
    <section id="section1" class="section" data-section="1">
      <header>Section 1</header>
    </section>
    
    <section id="section2" class="section" data-section="2">
      <header>Section 2</header>
    </section>
    
    <section id="section3" class="section" data-section="3">
      <header>Section 3</header>
    </section>
    
    <section id="section4" class="section" data-section="4">
      <header>Section 4</header>
    </section>
    
    <section id="section5" class="section" data-section="5">
      <header>Section 5</header>
    </section>
    

    JavaScript 代码

    var nav         = document.getElementById("navigation"),
        sections    = document.querySelectorAll(".section"),
        delay       = null;
    
    //---Scroll logic
    document.addEventListener("scroll", function(){
    
        if(!isNaN(delay)){ clearTimeout(delay); }
    
        delay = setTimeout(checkVisibleSection, 100);
    
    });
    
    //---Check the visible section
    function checkVisibleSection(){
    
        var minor   = window.innerHeight,
            section = null;
    
        //---Select the section closest to the top
        [].forEach.call(sections, function(item){
    
            var offset  = item.getBoundingClientRect();
    
            if(Math.abs(offset.top) < minor){
    
                minor   = Math.abs(offset.top);
    
                section = item;
    
            }
    
        });
    
        //---If the section exists
        if(section){
    
            var index   = section.dataset.section,
                link    = nav.querySelector("li[data-section='" + index + "'] a");
    
            //---If the link is not already active
            if(!link.classList.contains("active")){
    
                //---Remove the active class
                nav.querySelector("a.active").classList.remove("active");
    
                //---Add the active class
                link.classList.add("active");
    
            }
    
        }
    
    }
    
    //---Click on buttons
    nav.addEventListener("click", function(evt){
    
        evt.preventDefault();
    
        var link = evt.target;
    
        if(link.nodeName.toLowerCase() === "a"){
    
            var section = link.parentNode.dataset.section;
    
            //---Remove the class of the active link
            nav.querySelector("a.active").classList.remove("active");
    
            //---Active the link
            link.classList.add("active");
    
            //---Scroll to the section
            document.getElementById("section" + section).scrollIntoView();
    
            document.body.scrollTop -= 30;
    
        }
    
    });
    

    这里有一个 JSFiddle 和一个工作示例。

    【讨论】:

      猜你喜欢
      • 2019-02-12
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2019-02-27
      • 2022-10-13
      • 1970-01-01
      • 2020-03-28
      • 2013-01-28
      相关资源
      最近更新 更多