Bootstrap 3.0 scrollspy响应偏移

Ike*_*Ike 9 responsive-design twitter-bootstrap scrollspy twitter-bootstrap-3

我试图让Bootstrap的scrollspy在响应式网站上可靠地工作,其中顶部导航栏的高度根据媒体/浏览器的宽度而变化.因此,不是硬编码data-offset属性的偏移量,而是通过Javascript初始化动态设置它,如下所示:

$('body').scrollspy({ offset: 70, target: '#nav' });
Run Code Online (Sandbox Code Playgroud)

对于宽布局(即Bootstrap -lg),它可以正常工作,但对于较窄的布局,似乎存在"累积"偏移.换句话说,它适用于第一部分,但随后需要增加像素来激活以下部分(例如,下一个为90px,第三部分为110px等).

我尝试直接操作scrollspy对象,如下面的答案中所述: 如何在Bootstrap中设置ScrollSpy的偏移量?但无济于事.

有人可以推荐一种在响应式网站中实现scrollspy的规范方法,其中偏移量根据媒体宽度而变化吗?

附加信息:

我刚刚在两个场景中分析了scrollspy对象,结果发现当通过data-属性而不是通过JS 初始化时,偏移列表是不同的.看起来当我通过JS初始化它时,偏移数组会在一些BS响应调整发生之前填充,因此高度不同.所有响应式内容运行后,如何触发scrollspy的初始化?BS调整布局后是否有钩子/回调?JS是否参与或者是由CSS处理的所有响应式内容?

Tro*_*use 18

不幸的是,data-*$().data(...)第一次调用函数时,jQuery 只会引入一次属性.并且scrollspy只在初始化时读取选项一次.该refreshscrollspy的功能不装任何的选项.$(..).scrollspy(...)再次对同一元素进行调用会忽略任何新数据选项(使用先前初始化的值).

然而,scrollspy 确实选项值存储在项下的内容数据'bs.scrollspy'.因此,您可以更改该options.offset数据键中的字段.

要考虑动态更改的导航栏高度以及更改scrollspy偏移值的需要,可以将以下示例用于可变高度固定顶部导航栏.

以下是一些事情.

  • 它通过javascript初始化scrollspy(在window.load事件触发后),并以导航栏当前高度的偏移量开始(也将主体的padding-top值调整为与导航栏高度相同).
  • 监视调整大小事件并padding-top调整正文,并offset调整scrollspy 以匹配.然后refresh执行a以重新计算锚偏移.

HTML

<body>
  <style type="text/css">
    /* prevent navbar from collapsing on small screens */
    #navtop .navbar-nav > li { float: left !important; }
  </style>
  <nav id="navtop" class="navbar-fixed-top" role="navigation">
    <div class="container">
      <ul class="nav nav-pills navbar-nav">
        <li><a href="#one">One</a></li>
        <li><a href="#two">Two</a></li>
        <li><a href="#three">Three</a></li>
      ... some more navlinks, or dynamically added links that affect the height ...
      </ul>
    </div>
  </nav>
  <section id="one">
   ...
  </section>
  <section id="two">
   ...
  </section>
  <section id="three">
   ...
  </section>
   ....
</body>
Run Code Online (Sandbox Code Playgroud)

JavaScript的

$(window).on('load',function(){
    var $body   = $('body'), 
        $navtop = $('#navtop'),
        offset  = $navtop.outerHeight();

    // fix body padding (in case navbar size is different than the padding)
    $body.css('padding-top', offset);
    // Enable scrollSpy with correct offset based on height of navbar
    $body.scrollspy({target: '#navtop', offset: offset });

    // function to do the tweaking
    function fixSpy() {
        // grab a copy the scrollspy data for the element
        var data = $body.data('bs.scrollspy');
        // if there is data, lets fiddle with the offset value
        if (data) {
            // get the current height of the navbar
            offset = $navtop.outerHeight();
            // adjust the body's padding top to match
            $body.css('padding-top', offset);
            // change the data's offset option to match
            data.options.offset = offset;
            // now stick it back in the element
            $body.data('bs.scrollspy', data);
            // and finally refresh scrollspy
            $body.scrollspy('refresh');
        }
    }

    // Now monitor the resize events and make the tweaks
    var resizeTimer;
    $(window).resize(function() {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(fixSpy, 200);
    });
});
Run Code Online (Sandbox Code Playgroud)

就是这样.不漂亮,但绝对有效.我上面的HTML可能需要一些调整.

如果您动态地向导航栏添加元素,则需要fixSpy()在插入后调用它们.或者你可以fixSpy()通过setInterval(...)计时器来打电话一直运行.


Bas*_*sen 2

Scrollspy 在初始化后设置目标/偏移列表。如果您调整屏幕大小,滚动间谍不会再次初始化。您将需要重新加载页面以重新计算偏移量。

您提到的“累积”偏移量实际上是由具有不同内容高度的相同偏移量列表引起的。

要也可以触发此重新加载,请$(window).resize()注意某些浏览器会触发此两次,请参阅/sf/answers/300905741/了解解决方案:

var id; 

$(window).resize(function() 
{
    clearTimeout(id);
    id = setTimeout($('body').scrollspy({ target: '' }), 500);
});
Run Code Online (Sandbox Code Playgroud)

请注意http://getbootstrap.com/javascript/#scrollspy上的文档告诉您类似的内容:

“当使用scrollspy 结合在 DOM 中添加或删除元素时,您需要调用刷新方法”

有了上面的内容,你会得到类似的东西:

var id; 

$(window).resize(function() 
{
    clearTimeout(id);
    id = setTimeout($('[data-spy="scroll"]').each(function () {var $spy = $(this).scrollspy('refresh'}), 500);
});
Run Code Online (Sandbox Code Playgroud)

注意:scollspy 插件使用 jQuery 的 rollTop() 函数进行计算。因此,请阅读以下内容:http://blog.jonathanargentiero.com/?p =134 。