【问题标题】:How do I set the offset for ScrollSpy in Bootstrap?如何在 Bootstrap 中设置 ScrollSpy 的偏移量?
【发布时间】:2012-02-15 05:46:48
【问题描述】:

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

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

当您滚动通过 div 时,我成功地突出了菜单中的不同标题。

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

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

当它说您可以将 scrollspy 与 $('#navbar').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>

【问题讨论】:

  • 你为什么要给出一个位置:相对于你的div?也许这就是造成这种情况的原因。你能用你的代码创建一个 jsfiddle 以便我们看到实际效果吗?

标签: twitter-bootstrap


【解决方案1】:

Bootstrap 仅使用偏移来解决间谍问题,而不是滚动。这意味着滚动到正确的位置取决于您。

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

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

【讨论】:

  • 感谢您的回答。我花了很长时间才意识到偏移量不会影响滚动。这意味着任何使用固定顶的人都需要以这种方式手动调整。
  • 要正确更新 URL 的哈希部分,请将 window.location.hash = $(this).attr('href') 添加到此函数。
  • 谢谢! FWIW,将数据偏移量放在正文中也很重要,因为询问者说它没有做任何事情,但它是适当的间谍活动所必需的。有一个全面的答案可能会有所帮助。
  • 动态获胜:var navOffset = $('#navbar').height();scrollBy(0, -navOffset);
【解决方案2】:

正如 Tim 所暗示的,诀窍是利用填充。所以问题是,您的浏览器总是希望将您的锚点滚动到窗口的确切顶部。如果您将锚点设置在文本实际开始的位置,它将被菜单栏遮挡。相反,您所做的是将您的锚点设置为容器 &lt;section&gt;&lt;div&gt; 标签的 id,nav/navbar 将自动使用它们。然后,您必须将容器的padding-top 设置为您想要的偏移量,并将容器的margin-top 设置为padding-top对面。现在您的容器的块和锚点从页面的最顶部开始,但里面的内容直到菜单栏下方才开始。

如果您使用常规锚点,您可以通过在容器中使用负边距顶部来完成相同的操作,但没有填充。然后你把一个普通的&lt;a target="..."&gt; 锚作为容器的第一个孩子。然后使用相反但相等的margin-top 设置第二个子元素的样式,但使用选择器.container:first-child +

这一切都假定您的 &lt;body&gt; 标记已经将其边距设置为从您的标题下方开始,这是常态(否则页面将立即呈现被遮挡的文本)。

这是一个实际的例子。通过将#the-elements-id 添加到 URL 的末尾,可以链接到您页面上任何带有 id 的内容。如果您将所有 h 标签和 dt 标签与 ids 链接 (Like github does) 与 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;
}

【讨论】:

  • 喜欢 padding-top、负 margin-bottom(在同一个元素上)组合。然后更容易弄乱 js。
  • 看起来是最好的答案,但我有点失落。任何一个例子的机会。
  • @eddyparkinson,猜你现在想通了:例如,当你的 id 出现在 bootstrap 的行上时: .row[id] { padding-top: 60px;边距顶部:-40px; } 把它放在你的 less 文件中: .row[id]{ padding-top: 60px;边距顶部:-40px; }
  • 引导程序的默认偏移参数不应该用于此吗?包含它似乎是一件显而易见的事情,而不必求助于这样的解决方法。
  • 这是否有效地在您的目标 div 上增加了额外的空间?如果你不想要那个怎么办?一个不可见的额外间距是理想的。
【解决方案3】:

您可以使用此方法动态更改 scrollspy 的偏移量(假设您监视身体):

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

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

【讨论】:

  • 感谢您 - 对 Bootstrap 3.0 稍作调整后效果很好 $('body').data()['bs.scrollspy'].options.offset = newOffset; // 设置新的偏移量 $('body').data()['bs.scrollspy'].process(); // 强制 scrollspy 重新计算目标的偏移量 $('body').scrollspy('refresh'); // 刷新 scrollspy。
  • 我发现这个方法很好,但是如果我想用它来设置从一开始的偏移量,因为菜单高度不同,$('body').data() .scrollspy.options.offset(或 3.0 版的变体)尚未设置。我是否缺少关于 scrollspy 的异步内容?
  • 从 Bootstrap 3.1.1 开始,这应该是 $('body').data()['bs.scrollspy'].options.offset。对于使用window.scrollBy(X,Y) 在页面加载时触发 scrollspy 很有用
【解决方案4】:

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

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

你的身体标签应该是这样的:

<body data-spy="scroll">

【讨论】:

  • 这不是偏移内容,而是偏移导航。
  • 这将用于突出显示正确的导航元素,而不是点击导致的位置(这是原始海报问题)。话虽如此,这就是我要找的!谢谢!
【解决方案5】:

来自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; 
}

【讨论】:

    【解决方案6】:

    我认为偏移量可能会对部分的底部位置产生影响。

    我解决了我的问题 - 和你的一样 - 通过添加

      padding-top: 60px;
    

    在 bootstrap.css 部分的声明中

    希望有帮助!

    【讨论】:

    • 什么是“部分声明”你把这段代码放在哪里?
    【解决方案7】:

    我在每个 h1 元素之前添加了 40px 高度的 .vspace 元素来保持锚点。

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

    在 CSS 中:

    .vspace { height: 40px;}
    

    效果很好,空间也不拥挤。

    【讨论】:

      【解决方案8】:

      引导程序 4(2019 年更新)

      实现:固定导航、Scrollspy 和平滑滚动

      这是来自上述@wilfred-hughes 的解决方案,它完全修复了 Bootstrap Fixed Navbar 的重叠问题,方法是使用 CSS '::before' 在每个部分之前添加一个未显示的块标签。优点:您不会在部分之间出现不必要的填充。例如,第 3 部分可以垂直放置在第 2 部分的正上方,它仍然会滚动到第 3 部分顶部的准确位置。

      旁注:在脚本标签中设置 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 以上和用户@mnot https://github.com/twbs/bootstrap/issues/1768的原始来源

      【讨论】:

        【解决方案9】:

        我对 acjohnson55 和 Kurt UXD 的解决方案有疑问。两者都可以单击指向哈希的链接,但 scrollspy 偏移量仍然不正确。

        我想出了以下解决方案:

        <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 替换 40 像素的内边距/边距。

        在这个设置中,我什至可以观察到为 data-offset 属性设置值的效果。如果发现数据偏移量在 100-200 左右的较大值会导致更预期的行为(如果标题大约在屏幕中间,则会发生 scrollspy-“切换”)。

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

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

        【讨论】:

          【解决方案10】:

          看看这个post I made in another thread。这包含一个关于如何以编程方式更改偏移值并动态响应更改的 sn-p(例如,如果导航栏的大小发生变化)。

          您无需修补 CSS 修复,而是根据某些事件设置当前需要的偏移量。

          【讨论】:

            【解决方案11】:

            也可以打开bootstap-offset.js进行修改

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

            那里。

            【讨论】:

            • scrollspy 偏移量不会偏移内容,它会偏移导航。
            【解决方案12】:

            刚刚设置:

            data-offset="200"
            

            data-offset 默认为“50”,相当于 10px,所以只要增加data-offset,问题就解决了。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-02-07
              • 1970-01-01
              • 1970-01-01
              • 2015-12-08
              • 1970-01-01
              相关资源
              最近更新 更多