如何在Bootstrap中设置ScrollSpy的偏移量?

时间:2012-02-15 05:46:49

标签: twitter-bootstrap

我有一个网站,导航栏固定在顶部,主要内容区域下面有3个div。

我正在尝试使用bootstrap框架中的scrollspy。

当您滚动浏览div时,我已成功突出显示菜单中的不同标题。

我也有,所以当你点击菜单时,它会滚动到页面的正确部分。但是,偏移量不正确(它没有考虑导航栏,所以我需要偏移大约40个像素)

我在Bootstrap page上看到它提到了偏移选项,但我不确定如何使用它。

当它说你可以使用带有$('#navbar').scrollspy()的scrollspy时我也不是什么意思,我不知道在哪里包含它所以我没有,所有东西似乎都在工作(偏移除外)

我认为偏移可能是body标签上的data-offset='10',但它对我没有任何作用。

我感觉这是非常明显的事情,我只是错过了它。有什么帮助吗?

我的代码是

...
<!-- note: the data-offset doesn't do anything for me -->
<body data-spy="scroll" data-offset="20">
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
    <div class="container">
    <a class="brand" href="#">VIPS</a>
    <ul class="nav">
        <li class="active">
             <a href="#trafficContainer">Traffic</a>
        </li>
        <li class="">
        <a href="#responseContainer">Response Times</a>
        </li>
        <li class="">
        <a href="#cpuContainer">CPU</a>
        </li>
      </ul>
    </div>
</div>
</div>
<div class="container">
<div class="row">
    <div class="span12">
    <div id="trafficContainer" class="graph" style="position: relative;">
    <!-- graph goes here -->
    </div>
    </div>
</div>
<div class="row">
    <div class="span12">
    <div id="responseContainer" class="graph" style="position: relative;">
    <!-- graph goes here -->
    </div>
    </div>
</div>
<div class="row">
    <div class="span12">
    <div id="cpuContainer" class="graph" style="position: relative;">
    <!-- graph goes here -->
    </div>
    </div>
</div>
</div>

...
<script src="assets/js/jquery-1.7.1.min.js"></script>
<script src="assets/js/bootstrap-scrollspy.js"></script>
</body>
</html>

12 个答案:

答案 0 :(得分:105)

Bootstrap使用offset来解决间谍,而不是滚动。这意味着滚动到适当的位置取决于您。

试试这个,它适用于我:为导航点击添加一个事件处理程序。

var offset = 80;

$('.navbar li a').click(function(event) {
    event.preventDefault();
    $($(this).attr('href'))[0].scrollIntoView();
    scrollBy(0, -offset);
});

我在这里找到了它:https://github.com/twitter/bootstrap/issues/3316

答案 1 :(得分:74)

蒂姆提到的诀窍是利用填充。所以问题是,您的浏览器总是希望将锚点滚动到窗口的正确顶部。如果您将锚点设置在文本实际开始的位置,它将被菜单栏遮挡。相反,您所做的是将锚点设置为容器<section><div>标记的ID,导航/导航栏将自动使用该ID。然后,您必须将容器的padding-top设置为所需的金额偏移量,并将容器的margin-top设置为padding-top对面。现在您的容器块和锚点从页面的正确顶部开始,但内部的内容直到菜单栏下方才开始。

如果你使用常规锚点,你可以通过在容器中使用负margin-top来完成同样的事情,但是没有填充。然后,您将常规<a target="...">锚点作为容器的第一个子节点。然后使用相反但相等margin-top的第二个子元素设置样式,但使用选择器.container:first-child +

这一切都假定你的<body>标签已经将其边距设置为从标题下方开始,这是常态(否则页面会立即使用遮挡文本进行渲染)。

这是一个实例的例子。您可以通过将#the-elements-id添加到网址末尾来链接带有ID的网页上的任何内容。如果您将所有h标记ad dt标记与带有Like github does的ID可链接(some sort of script that injects a little link to the left of them);将以下内容添加到CSS中将为您处理导航栏偏移:

body {
    margin-top: 40px;/* make room for the nav bar */
}

/* make room for the nav bar */
h1[id],
h2[id],
h3[id],
h4[id],
h5[id],
h6[id],
dt[id]{
    padding-top: 60px;
    margin-top: -40px;
}

答案 2 :(得分:9)

你可以随意更改scrollspy的偏移(假设你监视身体):

offsetValue = 40;
$('body').data().scrollspy.options.offset = offsetValue;
// force scrollspy to recalculate the offsets to your targets
$('body').data().scrollspy.process();

如果您需要动态更改偏移值,这也适用。 (我喜欢在下一部分大约在窗口的一半时切换的scrollspy,所以我需要在窗口调整大小时更改偏移量。)

答案 3 :(得分:8)

如果你想要一个10的偏移量,你会把它放在脑中:

<script>
  $('#navbar').scrollspy({
    offset: 10
  });
</script>

你的身体标签看起来像这样:

<body data-spy="scroll">

答案 4 :(得分:4)

来自bootstrap issue #3316

  

[This]仅用于修改滚动计算 - 我们不会移动实际的锚点击

因此设置偏移仅影响,其中scrollspy认为页面滚动到。单击锚标记时,不会影响滚动

使用固定导航栏意味着浏览器滚动到错误的位置。您可以使用JavaScript解决此问题:

var navOffset = $('.navbar').height();

$('.navbar li a').click(function(event) {
    var href = $(this).attr('href');

    // Don't let the browser scroll, but still update the current address
    // in the browser.
    event.preventDefault();
    window.location.hash = href;

    // Explicitly scroll to where the browser thinks the element
    // is, but apply the offset.
    $(href)[0].scrollIntoView();
    window.scrollBy(0, -navOffset);
});

但是,要确保scrollspy突出显示正确的当前元素,您仍需要设置偏移量:

<body class="container" data-spy="scroll" data-target=".navbar" data-offset="70">

这是a complete demo on JSFiddle

或者,您可以填充到锚标记,如suggested by CSS tricks

a[id]:before { 
  display: block; 
  content: " ";
  // Use the browser inspector to find out the correct value here.
  margin-top: -285px; 
  height: 285px; 
  visibility: hidden; 
}

答案 5 :(得分:1)

我认为偏移量可能与该部分的底部位置有关。

我通过添加

修复了我的问题 - 与您的问题相同
  padding-top: 60px;

在bootstrap.css中的部分声明中

希望有所帮助!

答案 6 :(得分:1)

我在每个.vspace元素之前添加了40px-height h1元素。

<div class="vspace" id="gherkin"></div>
<div class="page-header">
  <h1>Gherkin</h1>
</div>

在CSS中:

.vspace { height: 40px;}

它工作得很好而且空间不大。

答案 7 :(得分:1)

Bootstrap 4(2019更新)

实施:固定的Nav,Scrollspy和平滑滚动

这是@ wilfred-hughes的解决方案,它精确地 使用CSS':before'在每个部分之前添加未显示的块,从而解决了Bootstrap Fixed Navbar的重叠问题标签。优势:您最终不会在各个部分之间留下不必要的填充。例如,第3部分可以垂直于第2部分垂直放置,并且仍会滚动到第3部分顶部的正确位置。

侧面说明:在script标记中设置scrollspy偏移不会导致任何事情($('#navbar')。scrollspy({     偏移量:105   });)并尝试在动画块中调整偏移仍导致动画后未对齐。

index.html

<section id="section1" class="my-5">
...
<section id="section2" class="my-5">
...
<section id="section3" class="my-5">
...

稍后在index.html中...

 <script>
      // Init Scrollspy
      $('body').scrollspy({ target: '#main-nav' });

      // Smooth Scrolling
      $('#main-nav a').on('click', function(event) {
        if (this.hash !== '') {
          event.preventDefault();

          const hash = this.hash;

          $('html, body').animate(
            {
              scrollTop: $(hash).offset().top
            },
            800,
            function() {
              window.location.hash = hash;
            }
          );
        }
      });
    </script>

style.css:

// Solution to Fixed NavBar overlapping content of the section.  Apply to each navigable section.
// adjust the px values to your navbar height
// Source: https://github.com/twbs/bootstrap/issues/1768
#section1::before,
#section2::before,
#section3::before {
  display: block;
  content: ' ';
  margin-top: -105px;
  height: 105px;
  visibility: hidden;
}

body {
  padding-top: 105px;
}

信用:上面的@ wilfred-hughes和来自{m3的用户@mnot的原始来源,位于https://github.com/twbs/bootstrap/issues/1768

答案 8 :(得分:0)

我对acjohnson55和Kurt UXD的解决方案有疑问。两者都用于单击哈希的链接,但是scrolllspy偏移仍然不正确。

我提出了以下解决方案:

<div class="anchor-outer">
  <div id="anchor">
    <div class="anchor-inner">
      <!-- your content -->
    </div>
  </div>
</div>

和相应的CSS:

body {
  padding-top:40px;
}

.anchor-outer {
  margin-top:-40px;
}

.anchor-inner {
  padding-top:40px;
}

@media (max-width: 979px) {
  body {
    padding-top:0px;
  }

  .anchor-outer {
    margin-top:0px;
  }

  .anchor-inner {
    padding-top:0px;
  }
}

@media (max-width: 767px) {
  body {
    padding-top:0px;
  }

  .anchor-outer {
    margin-top:0px;
  }

  .anchor-inner {
    padding-top:0px;
  }
}

您需要将导航栏的高度和锚点的ID替换为40px填充/边距。

在此设置中,我甚至可以观察到为数据偏移属性设置值的效果。如果为100-200左右的数据偏移找到较大的值会导致更期望的行为(如果标题大约位于屏幕中间,则会发生scrollspy-“switch”)。

我还发现scrollspy对非闭合div标签(非常明显)等错误非常敏感,所以http://validator.w3.org/check是我的朋友。

在我看来,scrolllspy最适合携带锚ID的整个部分,因为常规锚元素在向后滚动时不会产生预期效果(一旦你点击锚元素,就会发生scrollspy-“switch”,例如你的标题,但那时你已经滚动了用户期望属于相应标题的内容。

答案 9 :(得分:0)

如果您通过Google偶然发现了这个问题(就像我一样),并且仍在寻找一种动态更改scrollspy偏移量的方法。我现在将链接链接到一个对我有用的解决方案。

看看这个post I made in another thread。其中包含有关如何以编程方式更改偏移值并动态响应更改(例如,导航栏的大小是否更改)的摘要。

您不需要修改CSS修复程序,而可以根据某些事件设置当前所需的偏移量。

答案 10 :(得分:-1)

您也可以打开bootstap-offset.js并修改

$.fn.scrollspy.defaults = {
  offset: 10
}

那里。

答案 11 :(得分:-1)

刚设置:

data-offset="200"

data-offset默认为“50”,相当于10px,因此只需增加data-offset即可解决问题。