简体   繁体   English

如何创建一个滚动后固定在顶部的粘性导航栏

[英]How to create a sticky navigation bar that becomes fixed to the top after scrolling

I'm attempting to make a nav bar that appears at the bottom of the viewable page when the site is first loaded, then as the user scrolls down, the nav bar scrolls up, and eventually becomes fixed to the top.我正在尝试制作一个导航栏,该导航栏在首次加载网站时出现在可查看页面的底部,然后当用户向下滚动时,导航栏向上滚动,并最终固定在顶部。 I'm using Bootstrap, just like this site, but I can't figure out how this site did it.我正在使用 Bootstrap,就像这个网站一样,但我无法弄清楚这个网站是如何做到的。 Any help?有什么帮助吗?

Here's the site with the nav bar I'm trying to emulate: http://www.blastprocessor.co.uk/这是我试图模拟的带有导航栏的网站: http://www.blastprocessor.co.uk/

Here's my navigation html and css code:这是我的导航 html 和 css 代码:

HTML: 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 -->

And here's my CSS:这是我的 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;}

I was searching for this very same thing.我正在寻找同样的东西。 I had read that this was available in Bootstrap 3.0, but I was having no luck in actually implementing it.我读过这在 Bootstrap 3.0 中可用,但我没有真正实现它。 This is what I came up with and it works great.这是我想出来的,效果很好。 Very simple jQuery and Javascript.非常简单的 jQuery 和 Javascript。

Here is the JSFiddle to play around with... http://jsfiddle.net/CriddleCraddle/Wj9dD/这是 JSFiddle 玩... http://jsfiddle.net/CriddleCraddle/Wj9dD/

The solution is very similar to other solutions on the web and StackOverflow.该解决方案与网络和 StackOverflow 上的其他解决方案非常相似。 If you do not find this one useful, search for what you need.如果您觉得这个没有用,请搜索您需要的内容。 Goodluck!祝你好运!

Here is the HTML...这是 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>

Here is the CSS...这是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;
}

Now, just add the javacript to add and remove the fix class based on the scroll position.现在,只需添加 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');
    }
  });
});

Note (2015): Both question and the answer below apply to the old, deprecated version 2.x of Twitter Bootstrap .注意(2015):下面的问题和答案都适用于旧的、已弃用的 Twitter Bootstrap 2.x 版本

This feature of making and element "sticky" is built into the Twitter's Bootstrap and it is called Affix .这种制作和元素“粘性”的功能内置于 Twitter 的 Bootstrap 中,它被称为Affix All you have to do is to add:您所要做的就是添加:

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

around your tag and do not forget to load the Bootstrap's JS files as described in the manual .在你的标签周围,不要忘记按照手册中的描述加载 Bootstrap 的 JS 文件。 Data attribute offset-top tells how many pixels the page is scrolled (from the top) to fix you menu component.数据属性offset-top告诉你页面滚动了多少像素(从顶部)来修复你的菜单组件。 Usually it is just the space to the top of the page.通常它只是页面顶部的空间。

Note: You will have to take care of the missing space when the menu will be fixed.注意:当菜单被修复时,您必须处理丢失的空间。 Fixing means cutting it off out of your page layer and pasting in different layer that does not scroll.修复意味着将其从您的页面层中切除并粘贴到不滚动的不同层中。 I am doing the following:我正在做以下事情:

<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>

where 77px is the height of my affixed component.其中77px是我的附加组件的高度。

//in html //在html中

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

// add in jquery // 在 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');
       }
    });
});

Here is the jsfiddle to play around : - http://jsfiddle.net/shubhampatwa/46ovg69z/这是要玩的 jsfiddle: - http://jsfiddle.net/shubhampatwa/46ovg69z/

EDIT: if you want to apply this code only for mobile devices the you can use:编辑:如果您只想将此代码应用于移动设备,您可以使用:

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

Bootstrap 4 - Update 2020 Bootstrap 4 - 2020 年更新

The Affix plugin no longer exists in Bootstrap 4, but now most browsers support position:sticky which can be used to create a sticky after scoll Navbar. Bootstrap 4 中不再存在 Affix 插件,但现在大多数浏览器都支持position:sticky ,可用于在 scoll Navbar 后创建粘性。 Bootstrap 4 includes the sticky-top class for this... Bootstrap 4 包括用于此的sticky-top类...

https://codeply.com/go/oY2CyNiA7A https://codeply.com/go/oY2CyNiA7A

Bootstrap 3 - Original Answer Bootstrap 3 - 原始答案

Here's a Bootstrap 3 example that doesn't require extra jQuery.. it uses the Affix plugin included in Bootstrap 3, but the navbar markup has changed since BS2...这是一个不需要额外 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>

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

This worked great for me.这对我很有用。 Don't forget to put a filler div in there where the navigation bar used to be, or else the content will jump every time it's fixed/unfixed.不要忘记在导航栏曾经所在的位置放置一个填充 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');
        }
    });
}

Use Bootstrap Affix:使用 Bootstrap 词缀:

 /* 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>

For Bootstrap 4, a new class was released for this.对于 Bootstrap 4,为此发布了一个新类。 According to the utilties docs :根据实用程序文档

Apply the class sticky-top.应用类sticky-top。

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

For further navbar position options, visit here .如需更多导航栏位置选项, 请访问此处 Also, keep in mind that position: sticky;另外,请记住这个position: sticky; is not supported in every browser so this may not be the best solution for you if you need to support older browsers.并非每个浏览器都支持,因此如果您需要支持旧浏览器,这可能不是您的最佳解决方案。

You could use position: sticky您可以使用position: sticky

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

The #navbar should be a direct child of the body though.不过,#navbar 应该是 body 的直接子级。

In answer to Shubham Patwa: This way, the page is "jumpy" soon as the class "navbar-fixed-top" applies.回答 Shubham Patwa:这样,一旦应用“导航栏固定顶部”类,页面就会“跳跃”。 That's because the #mainnav is throwen in and out of the document's DOM flow.那是因为#mainnav 被扔进和扔出文档的 DOM 流。 This can result in an ugly UX if the page has a "critical height", jumping between fixed and un-fixed #mainnav position.如果页面具有“临界高度”,在固定和未固定的#mainnav 位置之间跳转,这可能会导致丑陋的用户体验。

I altered the code this way, which seems to work fine (not pixel-perfect, but fine):我以这种方式更改了代码,这似乎工作正常(不是像素完美,但很好):

$(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');
   }
});

I have found this simple javascript snippet very useful.我发现这个简单的 javascript 片段非常有用。

$(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');
        }
    });
});
.navBar{
position: sticky;
top: 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM