【问题标题】:How to create a sticky navigation bar that becomes fixed to the top after scrolling如何创建滚动后固定在顶部的粘性导航栏
【发布时间】:2013-01-18 00:52:16
【问题描述】:

我正在尝试制作一个导航栏,该导航栏在网站首次加载时显示在可查看页面的底部,然后当用户向下滚动时,导航栏会向上滚动,最终固定在顶部。我正在使用 Bootstrap,就像这个网站一样,但我不知道这个网站是如何做到的。有什么帮助吗?

这是我试图模仿的带有导航栏的网站:http://www.blastprocessor.co.uk/

这是我的导航 html 和 css 代码:

HTML:

<div class="navbar navbar-fixed-top" id="navbar">
    <div class="navbar-inner">
        <div class="container">
            <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            </a>
            <div class="nav-collapse">
                <ul class="nav nav-pills">
                    <li class="active"><a href="#home">Home</a></li>
                    <li><a href="#service-link">Services</a></li>
                    <li><a href="#contact-link">Contact</a></li>
                </ul><!-- /.nav -->
            </div><!--/.nav-collapse -->
        </div><!-- /.container -->
    </div><!-- /.navbar-inner -->
</div><!-- /.navbar -->

这是我的 CSS:

.navbar-fixed-top,.navbar-fixed-bottom{position:fixed; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none;}
.navbar .nav > li a{
    color:white; background:rgba(0,0,0,0.2); text-shadow:none; font-size:1.7em; font-family: marvel, serif; padding:.5em 1.3em; margin:1em 2em;
}
.navbar .nav > .active a:hover, .navbar .nav > li a:hover, .navbar .nav > .active a {
    color:white; ; background:#F90; text-shadow:none; font-size:1.7em; font-family: marvel, serif; padding:.5em 1.3em; margin:1em 2em;
}
.navbar .nav > li {padding:2em;}
.navbar.navbar-fixed-top .navbar-inner{background: rgba(255, 255, 255, 0);}
.navbar .nav, .navbar .nav > li {
    float:none;
    display:inline-block;
    *display:inline; /* ie7 fix */
    *zoom:1; /* hasLayout ie7 trigger */
    vertical-align: top;
    padding:0 2em;
}
.navbar-inner {text-align:center;}
.navbar .navbar-inner, .navbar .navbar-inner {border: none; box-shadow: none; filter: none;}

【问题讨论】:

    标签: javascript html css twitter-bootstrap nav


    【解决方案1】:

    引导程序 4 - 2020 年更新

    Affix 插件在 Bootstrap 4 中不再存在,但现在大多数浏览器都支持position:sticky,可用于在 scoll 导航栏之后创建一个粘性。 Bootstrap 4 包含 sticky-top 类...

    https://codeply.com/go/oY2CyNiA7A

    Bootstrap 3 - 原始答案

    这是一个不需要额外 jQuery 的 Bootstrap 3 示例。它使用 Bootstrap 3 中包含的 Affix 插件,但导航栏标记自 BS2 以来发生了变化...

    <!-- Content Above Nav -->
    <header class="masthead">
    
    </header>           
    
    
    <!-- Begin Navbar -->
    <div id="nav">
      <div class="navbar navbar-default navbar-static">
        <div class="container">
          <!-- .btn-navbar is used as the toggle for collapsed navbar content -->
          <a class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="glyphicon glyphicon-bar"></span>
            <span class="glyphicon glyphicon-bar"></span>
            <span class="glyphicon glyphicon-bar"></span>
          </a>
          <div class="navbar-collapse collapse">
            <ul class="nav navbar-nav">
              <li class="active"><a href="#">Home</a></li>
              <li class="divider"></li>
              <li><a href="#">Link</a></li>
              <li><a href="#">Link</a></li>
            </ul>
            <ul class="nav pull-right navbar-nav">
              <li>
                ..
              </li>
              <li>
                ..
              </li>
            </ul>
          </div>        
        </div>
      </div><!-- /.navbar -->
    </div>
    

    工作演示/模板:http://bootply.com/69848

    【讨论】:

    • 它跳得太多,看起来不太好
    【解决方案2】:

    我正在寻找同样的东西。我读过这在 Bootstrap 3.0 中可用,但我在实际实现它时没有运气。这就是我想出的,而且效果很好。非常简单的 jQuery 和 Javascript。

    这里是可以玩的 JSFiddle...http://jsfiddle.net/CriddleCraddle/Wj9dD/

    该解决方案与 web 和 StackOverflow 上的其他解决方案非常相似。如果您不觉得这个有用,请搜索您需要的内容。祝你好运!

    这里是 HTML...

    <div id="banner">
      <h2>put what you want here</h2>
      <p>just adjust javascript size to match this window</p>
    </div>
    
      <nav id='nav_bar'>
        <ul class='nav_links'>
          <li><a href="url">Sign In</a></li>
          <li><a href="url">Blog</a></li>
          <li><a href="url">About</a></li>
        </ul>
      </nav>
    
    <div id='body_div'>
      <p style='margin: 0; padding-top: 50px;'>and more stuff to continue scrolling here</p>
    </div>
    

    这里是 CSS...

    html, body {
      height: 4000px;
    }
    
    .navbar-fixed {
      top: 0;
      z-index: 100;
      position: fixed;
      width: 100%;
    }
    
    #body_div {
      top: 0;
      position: relative;
      height: 200px;
      background-color: green;
    }
    
    #banner {
      width: 100%;
      height: 273px;
      background-color: gray;
      overflow: hidden;
    }
    
    #nav_bar {
      border: 0;
      background-color: #202020;
      border-radius: 0px;
      margin-bottom: 0;
      height: 30px;
    }
    
    //the below css are for the links, not needed for sticky nav
    .nav_links {
      margin: 0;
    }
    
    .nav_links li {
      display: inline-block;
      margin-top: 4px;
    }
    
    .nav_links li a {
      padding: 0 15.5px;
      color: #3498db;
      text-decoration: none;
    }
    

    现在,只需添加 javacript 即可根据滚动位置添加和删除修复类。

    $(document).ready(function() {
      //change the integers below to match the height of your upper div, which I called
      //banner.  Just add a 1 to the last number.  console.log($(window).scrollTop())
      //to figure out what the scroll position is when exactly you want to fix the nav
      //bar or div or whatever.  I stuck in the console.log for you.  Just remove when
      //you know the position.
      $(window).scroll(function () { 
    
        console.log($(window).scrollTop());
    
        if ($(window).scrollTop() > 550) {
          $('#nav_bar').addClass('navbar-fixed-top');
        }
    
        if ($(window).scrollTop() < 551) {
          $('#nav_bar').removeClass('navbar-fixed-top');
        }
      });
    });
    

    【讨论】:

    • +1 并且我还创建了一个非硬编码版本,它还负责处理滚动条宽度(如果它不必是 100% 以及重叠的 body_div 希望这会有所帮助。
    • 注意;确保检查哪些浏览器支持 position:fixed: caniuse.com/#feat=css-fixed
    • @TheCarver 注意:都是他们(即使在 2015 年)。
    【解决方案3】:

    对于 Bootstrap 4,为此发布了一个新类。根据实用程序docs

    应用类sticky-top。

    <div class="sticky-top">...</div>
    

    更多导航栏位置选项,visit here。 另外,请记住,并非所有浏览器都支持position: sticky;,因此如果您需要支持旧版浏览器,这可能不是您的最佳解决方案。

    【讨论】:

      【解决方案4】:

      //在html中

      <nav class="navbar navbar-default" id="mainnav">
      <nav>
      

      //在jquery中添加

      $(document).ready(function() {
        var navpos = $('#mainnav').offset();
        console.log(navpos.top);
          $(window).bind('scroll', function() {
            if ($(window).scrollTop() > navpos.top) {
             $('#mainnav').addClass('navbar-fixed-top');
             }
             else {
               $('#mainnav').removeClass('navbar-fixed-top');
             }
          });
      });
      

      这里是 jsfiddle:-http://jsfiddle.net/shubhampatwa/46ovg69z/

      编辑: 如果您只想将此代码应用于您可以使用的移动设备:

         var newWindowWidth = $(window).width();
          if (newWindowWidth < 481) {
              //Place code inside it...
             }
      

      【讨论】:

        【解决方案5】:

        使用引导词缀:

        /* Note: Try to remove the following lines to see the effect of CSS positioning */
          .affix {
              top: 0;
              width: 100%;
          }
        
          .affix + .container-fluid {
              padding-top: 70px;
          }
        <!DOCTYPE html>
        <html>
        <head>
          <title>Bootstrap Example</title>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
          <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
          
        </head>
        <body>
        
        <div class="container-fluid" style="background-color:#F44336;color:#fff;height:200px;">
          <h1>Bootstrap Affix Example</h1>
          <h3>Fixed (sticky) navbar on scroll</h3>
          <p>Scroll this page to see how the navbar behaves with data-spy="affix".</p>
          <p>The navbar is attached to the top of the page after you have scrolled a specified amount of pixels.</p>
        </div>
        
        <nav class="navbar navbar-inverse" data-spy="affix" data-offset-top="197">
          <ul class="nav navbar-nav">
            <li class="active"><a href="#">Basic Topnav</a></li>
            <li><a href="#">Page 1</a></li>
            <li><a href="#">Page 2</a></li>
            <li><a href="#">Page 3</a></li>
          </ul>
        </nav>
        
        <div class="container-fluid" style="height:1000px">
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
          <h1>Some text to enable scrolling</h1>
        </div>
        
        </body>
        </html>

        【讨论】:

          【解决方案6】:

          对 Shubham Patwa 的回答:这样一来,一旦应用“navbar-fixed-top”类,页面就会“跳跃”。那是因为#mainnav 被扔进和扔出文档的DOM 流。如果页面具有“临界高度”,在固定和不固定的#mainnav 位置之间跳转,这可能会导致丑陋的用户体验。

          我以这种方式更改了代码,这似乎工作正常(不是像素完美,但很好):

          $(document).ready(function() {
            var navpos = $('#mainnav').offset();
            var navheight = $('#mainnav').outerHeight();
          
          $(window).bind('scroll', function() {
            if ($(window).scrollTop() > navpos.top) {
             $('#mainnav').addClass('navbar-fixed-top');
             $('body').css('marginTop',navheight);
             }
             else {
               $('#mainnav').removeClass('navbar-fixed-top');
               $('body').css('marginTop','0');
             }
          });
          

          【讨论】:

            【解决方案7】:

            注意(2015 年):以下问题和答案均适用于已弃用的旧 version 2.x of Twitter Bootstrap

            这种制作和元素“粘性”的功能内置在 Twitter 的 Bootstrap 中,称为Affix。您所要做的就是添加:

            <div data-spy="affix" data-offset-top="121">
              ... your navbar ...
            </div>
            

            在你的标签周围,不要忘记加载 Bootstrap 的 JS 文件,如manual 中所述。数据属性offset-top 告诉页面滚动了多少像素(从顶部)以修复您的菜单组件。通常它只是到页面顶部的空间。

            注意:修复菜单时,您必须注意缺少的空间。修复意味着将其从页面图层中删除并粘贴到不滚动的不同图层中。我正在执行以下操作:

            <div style="height: 77px;">
              <div data-spy="affix" data-offset-top="121">
                <div style="position: relative; height: 0; width: 100%;">
                  <div style="position: absolute; top: 0; left: 0;">
                    ... my menu ...
                  </div>
                </div>
              </div>
            </div>
            

            77px 是我的附加组件的高度。

            【讨论】:

              【解决方案8】:

              我发现这个简单的 javascript sn-p 非常有用。

              $(document).ready(function()
              {
                  var navbar = $('#navbar');
              
                  navbar.after('<div id="more-div" style="height: ' + navbar.outerHeight(true) + 'px" class="hidden"></div>');
                  var afternavbar = $('#more-div');
              
                  var abovenavbar = $('#above-navbar');
              
                  $(window).on('scroll', function()
                  {
                      if ($(window).scrollTop() > abovenavbar.height())
                      {
                          navbar.addClass('navbar-fixed-top');
                          afternavbar.removeClass('hidden');
                      }
                      else
                      {
                          navbar.removeClass('navbar-fixed-top');
                          afternavbar.addClass('hidden');
                      }
                  });
              });
              

              【讨论】:

                【解决方案9】:

                你可以使用position: sticky

                #navbar {
                  position: sticky;
                  top: 0px;
                }
                

                #navbar 应该是 body 的直接子元素。

                【讨论】:

                • 这是最好的解决方案,但目前它只适用于 FireFox :((
                【解决方案10】:

                这对我很有用。不要忘记在导航栏原来的位置放一个填充 div,否则每次固定/不固定时内容都会跳转。

                function setSkrollr(){
                    var objDistance = $navbar.offset().top;
                    $(window).scroll(function() {
                        var myDistance = $(window).scrollTop();
                        if (myDistance > objDistance){
                            $navbar.addClass('navbar-fixed-top');
                        }
                        if (objDistance > myDistance){
                            $navbar.removeClass('navbar-fixed-top');
                        }
                    });
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-01-18
                  • 2021-08-16
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多