【问题标题】:Highlighting links based on scroll position根据滚动位置突出显示链接
【发布时间】:2017-04-19 15:41:15
【问题描述】:

如果用户正在滚动该链接的页面,我试图让我的链接突出显示。但由于某种原因,它无法正常工作。我已经注释掉了我在 jquery 中的第一次尝试并再次尝试,但是当链接一个应该时,链接二会突出显示。

<nav>
  <ul>
    <li><a href="" id="link_1">Link 1</a></li>
    <li><a href="" id="link_2">Link 2</a></li>
    <li><a href="" id="link_3">Link 3</a></li>
  </ul>
   <p></p>
</nav>

<div id="sec_one" class="sections">

</div>

<div id="sec_two" class="sections">

</div>

<div id="sec_three" class="sections">

</div>

<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>

*{
  margin: 0;
  padding: 0;
}
nav{
  width: 100%;
  background-color: black;
  position: fixed;
  top: 0;
}

nav ul{
  width: 50%;
  margin: 0 auto;
  list-style-type: none;
  text-align: center;
}

nav ul li{
  display: inline;
  width: 100%;
}

nav ul li a{
  font-size: 40px;
  color: white;
  text-decoration: none;
}

nav ul li a{

}

.sections{
  width: 100%;
  height: 2000px;
}

#sec_one{
  background-color: blue;
}

#sec_two{
  background-color: red;
}

#sec_three{
  background-color: yellow;
}

.active{
  background-color: #666666;
}

p{
  color: white;
}

$(window).scroll(function(){
  var scrollPos = $(window).scrollTop();
  var page1Top = $("#sec_one").scrollTop();
  var page1Bot = $("#sec_one").outerHeight();

  var page2Top = $("#sec_two").scrollTop();
  var page2Bot = $("#sec_two").outerHeight();

  var page3Top = $("#sec_three").scrollTop();
  var page3Bot = $("#sec_three").outerHeight();

 /*if(scrollPos >= page1Top && scrollPos < page1Bot){
    $("#link_1").addClass("active");
    $("#link_2").removeClass("active");
    $("#link_3").removeClass("active");
  }else if(scrollPos >= page2Top && scrollPos < page2Bot){
    $("#link_1").removeClass("active");
    $("#link_3").removeClass("active");
    $("#link_2").addClass("active");
  }else if(scrollPos >= page3Top && scrollPos < page3Bot){
    $("#link_3").addClass("active");
    $("#link_1").removeClass("active");
    $("#link_2").removeClass("active");
  }*/

  if(scrollPos >= page1Top && scrollPos < page1Bot){
    $("#link_1").addClass("active");
    $("#link_2").removeClass("active");
    $("#link_3").removeClass("active");
    }else {
      $("#link_1").removeClass("active");
    }

  if(scrollPos >= page2Top && scrollPos < page2Bot){
    $("#link_2").addClass("active");
    $("#link_1").removeClass("active");
    $("#link_3").removeClass("active");
    }else {
      $("#link_2").removeClass("active");
    }

});

【问题讨论】:

    标签: javascript jquery html css


    【解决方案1】:

    您的主要问题是您没有使用.offset() - 使用您的代码,您只是获得相对于自身的位置,因此顶部始终变为0,底部变为2000 - 使用offset 意味着您将获得相对于文档的位置,以便它也考虑其他元素。

    您也不需要检查底部位置。您可以只使用下一部分的顶部位置。

    $(document).ready(function() {
      $(window).scroll(function() {
        var scrollPos = $(window).scrollTop();
        
        var page1Top = $("#sec_one").offset().top;
        var page2Top = $("#sec_two").offset().top;
        var page3Top = $("#sec_three").offset().top;
    
        if (scrollPos >= page1Top && scrollPos < page2Top) {
          $("#link_1").addClass("active");
          $("#link_2").removeClass("active");
          $("#link_3").removeClass("active");
        } else {
          $("#link_1").removeClass("active");
        }
    
        if (scrollPos >= page2Top && scrollPos < page3Top) {
          $("#link_2").addClass("active");
          $("#link_1").removeClass("active");
          $("#link_3").removeClass("active");
        } else {
          $("#link_2").removeClass("active");
        }
        
        if (scrollPos >= page3Top) {
          $("#link_3").addClass("active");
          $("#link_1").removeClass("active");
          $("#link_2").removeClass("active");
        } else {
          $("#link_3").removeClass("active");
        }
    
      });
    });
    * {
      margin: 0;
      padding: 0;
    }
    
    nav {
      width: 100%;
      background-color: black;
      position: fixed;
      top: 0;
    }
    
    nav ul {
      width: 50%;
      margin: 0 auto;
      list-style-type: none;
      text-align: center;
    }
    
    nav ul li {
      display: inline;
      width: 100%;
    }
    
    nav ul li a {
      font-size: 40px;
      color: white;
      text-decoration: none;
    }
    
    nav ul li a {}
    
    .sections {
      width: 100%;
      height: 2000px;
    }
    
    #sec_one {
      background-color: blue;
    }
    
    #sec_two {
      background-color: red;
    }
    
    #sec_three {
      background-color: yellow;
    }
    
    .active {
      background-color: #666666;
    }
    
    p {
      color: white;
    }
    <nav>
      <ul>
        <li><a href="" id="link_1">Link 1</a></li>
        <li><a href="" id="link_2">Link 2</a></li>
        <li><a href="" id="link_3">Link 3</a></li>
      </ul>
      <p></p>
    </nav>
    
    <div id="sec_one" class="sections"></div>
    <div id="sec_two" class="sections"></div>
    <div id="sec_three" class="sections"></div>
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

    【讨论】:

      【解决方案2】:

      避免单个元素的目标和使用粗略的ID,您可以评估元素的scrollTopoffset().top,并根据部分的索引突出显示您需要的项目:

      $(window).scroll(function() {
        var scrollPos = $(window).scrollTop(),
            navH     = $('nav').height();
        $('.sections').each(function(i){
          var offT = $(this).offset().top;
          if((offT-scrollPos-navH) <= 0) {
            $('.active').removeClass('active')
            $('nav a').eq(i).addClass('active')
          }
        })
      });
      * { margin: 0; padding: 0;} nav { width: 100%; background-color: black; position: fixed; top: 0;} nav ul { width: 50%; margin: 0 auto; list-style-type: none; text-align: center;} nav ul li { display: inline; width: 100%;} nav ul li a { font-size: 40px; color: white; text-decoration: none;} .sections { width: 100%; height: 2000px;} #sec_one { background-color: blue;} #sec_two { background-color: red;} #sec_three { background-color: yellow;} .active { background-color: #666666;} p { color: white;}
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <nav>
        <ul>
          <li><a href="" id="link_1" class="active">Link 1</a></li>
          <li><a href="" id="link_2">Link 2</a></li>
          <li><a href="" id="link_3">Link 3</a></li>
        </ul>
        <p></p>
      </nav>
      <div id="sec_one" class="sections"></div>
      <div id="sec_two" class="sections"></div>
      <div id="sec_three" class="sections"></div>

      【讨论】:

        【解决方案3】:

        所以,我假设您希望链接链接到页面上的不同 div,而不是完全不同的页面。

        您可以使用ScrollSpy 轻松完成此操作。可以在here 找到文档。

        以下是一些示例代码,说明如何在页面上执行此操作:

        首先,引用scrollspy.js 文件。请务必根据您选择保存文件的位置使用相对 url。

        &lt;script src="scrollspy.js"&gt;&lt;/script&gt;

        然后,在你的页面脚本文件中,你可以有这样的东西。

        $('.sections').on('scrollSpy:enter', function() {
          switch($(this).attr('id')) {
            case "sec_one":
              $("#link_1").addClass("active");
              $("#link_2").removeClass("active");
              $("#link_3").removeClass("active");
              break;
            case "sec_two":
              $("#link_1").removeClass("active");
              $("#link_2").addClass("active");
              $("#link_3").removeClass("active");
              break;
            case "sec_three":
              $("#link_1").removeClass("active");
              $("#link_2").removeClass("active");
              $("#link_3").addClass("active");
              break;
          }
        }
        
        $('.sections').scrollSpy();
        

        【讨论】:

          【解决方案4】:

          稍微改写一下,这样您就不用计算 JS 中的每个单独元素,您只需动态找到滚动到的 div 并修改匹配的导航元素的类。

          var $sections = $('.sections'),
              $lis = $('nav li');
          
          $(window).on('scroll', function(){
            var scrollPos = $(window).scrollTop(),
                navHeight = $('nav').outerHeight();
            $sections.each(function() {
              var top = $(this).offset().top,
                  bottom = top + $(this).outerHeight();
              if (scrollPos > top - navHeight && scrollPos < bottom) {
                var $target = $lis.eq($(this).index() - 1);
                $lis.not($target).removeClass('active');
                $target.addClass('active');
              }
            })
          });
          *{
            margin: 0;
            padding: 0;
          }
          nav{
            width: 100%;
            background-color: black;
            position: fixed;
            top: 0;
          }
          
          nav ul{
            width: 50%;
            margin: 0 auto;
            list-style-type: none;
            text-align: center;
          }
          
          nav ul li{
            display: inline-block;
          }
          
          nav ul li a{
            font-size: 40px;
            color: white;
            text-decoration: none;
            display: inline-block;
          }
          
          .sections{
            height: 200vh;;
          }
          
          #sec_one{
            background-color: blue;
          }
          
          #sec_two{
            background-color: red;
          }
          
          #sec_three{
            background-color: yellow;
          }
          
          .active{
            background-color: #666666;
          }
          
          p{
            color: white;
          }
          <nav>
            <ul>
              <li><a href="" id="link_1">Link 1</a></li>
              <li><a href="" id="link_2">Link 2</a></li>
              <li><a href="" id="link_3">Link 3</a></li>
            </ul>
            <p></p>
          </nav>
          
          <div id="sec_one" class="sections">
          
          </div>
          
          <div id="sec_two" class="sections">
          
          </div>
          
          <div id="sec_three" class="sections">
          
          </div>
          
          <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

          【讨论】:

          • 更多反对票!如果我的回答对 OP 没有帮助,我很乐意听到一些反馈。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-11-05
          • 1970-01-01
          • 1970-01-01
          • 2019-08-10
          • 1970-01-01
          • 2022-10-20
          • 2010-09-15
          相关资源
          最近更新 更多