简体   繁体   English

Twitter的Bootstrap固定到顶部导航栏滚动,页面内锚链接弹跳

[英]Twitter's Bootstrap fixed-to-top navbar on scroll with in-page anchor links bouncing

I have a web page with a top horizontal navigation bar – it is Twitter's Bootstrap Fixed Top Navbar to be more precise – with a bottom-fixed position (actually it's not really fixed by CSS; see JavaScript below) so the navigation bar will first be visible at the bottom of the page and later displayed at the top of the page when scrolling ( position: fixed; top: 0 ). 我有一个带有顶部水平导航栏的网页-更确切地说是Twitter的Bootstrap固定顶部导航栏-底部固定的位置(实际上CSS并没有真正固定它;请参见下面的JavaScript),因此导航栏将首先是在页面底部可见,然后在滚动时显示在页面顶部( position: fixed; top: 0 )。

I have the navigation links set up with anchor tags to take the viewer to various places in the body of the page. 我的导航链接设置了定位标记,以将查看器带到页面正文中的各个位置。 Unfortunately, sometimes it takes the user a bit too far down (especially if the user is at the top of the page and the navigation bar has not yet became fixed). 不幸的是,有时这会使用户走得太远(特别是如果用户位于页面顶部并且导航栏尚未固定)。

Take a look at my HTML structure: 看一下我的HTML结构:

<div id="landing"></div>
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li><a href="#landing">Home</a></li>
        <li><a href="#section1">Section 1</a></li>
        <li><a href="#section2">Section 2</a></li>
        <li><a href="#section3">Section 3</a></li>
      </ul>
    </div>
  </div>
</nav>
<div id="section1"></div>
<div id="section2"></div>
<div id="section3"></div>

I'm using the following JavaScript to ensure that the navbar sticks to the top of the page after scrolling down: 我正在使用以下JavaScript,以确保向下滚动后导航栏停留在页面顶部:

function init() {
  nh = 50; // navbar height
  sh = $(window).height();
  ih = sh-nh;            
  $("#landing").css('height', ih+'px');
} 

function navbarState() {
  if ($(window).scrollTop() > ih) {
        $('.navbar').addClass('navbar-fixed-top');
      } else {
        $('.navbar').removeClass('navbar-fixed-top');
      }
}

init();
navbarState();

$(window).on('load scroll resize orientationchange', function () {
    init();
    navbarState();
});

One can observe that repeatedly pressing the first anchor link causes a bouncing effect. 可以观察到,反复按下第一根锚杆会产生弹跳效果。 How can I prevent that? 我该如何预防?

My goal is to have the navigation scroll to the proper anchors, no matter whether the user is at the landing page or not. 我的目标是使导航滚动到适当的锚点,而不管用户是否在目标网页上。

Why not using navbar-fixed-bottom as well? 为什么不同时使用navbar-fixed-bottom

See here: https://jsfiddle.net/y7soL4ej/ 看到这里: https : //jsfiddle.net/y7soL4ej/


I added the mentioned class as default to nav . 我将提到的类作为默认添加到nav And modified minor things: 并修改了小事:

CSS 的CSS

html, body, div#landing {
  height: 100%
}
section, [id*=section] {
  padding-top: 52px;
}

JS JS

function init() {
  nh = 50 + 2; // navbar height + 2x border width (top + bottom)
  sh = $(window).height();
  ih = sh-nh;            
  //$("#landing").css('height', ih+'px');
}

function navbarState() {
  if ($(window).scrollTop() > ih) {
        $('.navbar').removeClass('navbar-fixed-bottom').addClass('navbar-fixed-top');
      } else {
        $('.navbar').removeClass('navbar-fixed-top').addClass('navbar-fixed-bottom');
      }
}

init();
navbarState();

$(window).on('load scroll resize orientationchange', function () {
    init();
    navbarState();
});

The jumpy behaviour: When the navbar is at the bottom in your example it is part of the dom flow - it seperates the landing div and the section1 div by its height. 跳动的行为:在您的示例中,导航栏位于底部时,它是dom流的一部分-它按其高度将着陆 div和section1 div分开。 As soon as it is clicked the browser jumps to the location, the navbar is then set as fixed at the top - and is no longer part of the flow (the both divs are no longer seperated by it). 单击浏览器后,浏览器将跳转到该位置,然后将导航栏设置为固定在顶部-不再是流的一部分(两个div不再被其分隔)。 The section divs are therefore moved accordingly up to the landing div closing the gap. 因此, 部分 div相应地向上移动到着陆 div,以缩小间隙。 So clicking the same section anchor again will result in an additional jump, because the section was repositioned due to the landing div went from position:static to position:fixed . 因此,再次单击同一部分锚点将导致额外的跳转,因为由于着陆 div从position:staticposition:fixed ,该部分被重新定位。

That's an additional reason why I recommend to use navbar-fixed-bottom . 这是我建议使用navbar-fixed-bottom的另一个原因。


Update 更新资料

new fiddle: https://jsfiddle.net/y7soL4ej/2/ 新提琴: https : //jsfiddle.net/y7soL4ej/2/

I removed .navbar-fixed-bottom from HTML and JS as the navbar should not jump from bottom to top. 我从HTML和JS中删除了.navbar-fixed-bottom ,因为导航栏不应从底部跳到顶部。 To make it smooth and avoid the earlier mentioned jumpy behaviour, I had to set it to absolute position. 为了使其平滑并避免前面提到的跳动行为,我必须将其设置为绝对位置。

some CSS needed to be added: 需要添加一些CSS

div#landing {
  padding-bottom: 72px;
  margin-bottom: -72px;
}

nav.navbar {
  position: absolute;
  left: 0; right: 0;
}
nav.navbar.navbar-fixed-top {
  position: fixed;
}

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

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