Bootstrap 3.0 scrollspy响应式偏移 [英] Bootstrap 3.0 scrollspy responsive offsets

查看:86
本文介绍了Bootstrap 3.0 scrollspy响应式偏移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使Bootstrap的scrollspy在响应站点​​上可靠地工作,该站点上的顶部导航栏的高度根据媒体/浏览器的宽度而变化.因此,不是通过硬编码data-offset属性上的偏移量,而是通过像这样的Javascript初始化来动态设置它:

I'm trying to get Bootstrap's scrollspy to work reliably on a responsive site on which the top navbar's height changes according to the width of the media/browser. So instead of hardcoding the offset on the data-offset attribute I'm setting it dynamically through Javascript initialization like this:

$('body').scrollspy({ offset: 70, target: '#nav' });

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

For wide layouts (i.e. Bootstrap -lg) it works fine but for narrower layouts there seems to be an "accumulating" offset in effect. In other words, it works fine for the first section but then takes increasing pixels to activate the following ones (e.g. 90px for the next, 110px for the 3rd, etc.).

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

I tried manipulating the scrollspy object directly as mentioned in this answer: How do I set the offset for ScrollSpy in Bootstrap? but to no avail.

有人可以推荐一种在响应站点​​中实现滚动滚动的规范方法吗,该站点的偏移量根据媒体宽度而有所不同?

Can someone recommend a canonical way of implementing scrollspy in a responsive site where the offset varies according to the media width?

其他信息:

我刚刚分析了这两种情况下的scrollspy对象,结果发现,仅通过data-属性与通过JS进行初始化时,偏移量列表是不同的.似乎当我通过JS初始化偏移数组时,会在进行一些BS响应性调整之前填充偏移数组,因此高度有所不同.在所有响应式内容运行完毕后,如何触发scrollspy的初始化 ? BS调整布局后是否有挂机/回调? JS是否参与其中,或者所有响应式内容都由CSS处理?

I just analyzed the scrollspy object in both scenarios and it turns out that the list of offsets is different when it's initialized through data- attributes only vs. via JS. It seems like when I initialize it via JS the offsets array gets populated before some of BS responsive adjustments happen and therefore the heights are different. How can I trigger scrollspy's initialization after all the responsive stuff has run? Is there a hook/callback after BS is done adjusting the layout? Is JS even involved or is all the responsive stuff handled by CSS?

推荐答案

不幸的是,当第一次调用$().data(...)函数时,jQuery仅将data-*属性拉入一次.并且scrollspy在初始化时仅读取一次选项. scrollspy的refresh函数不会重新加载任何选项.在同一元素上再次调用$(..).scrollspy(...)会忽略任何新的数据选项(使用先前初始化的值).

Unfortunately jQuery pulls in the data-* attributes only once when the $().data(...) function is called the first time. And scrollspy only reads the options once when it is initialised. The refresh function of scrollspy does not reload any of the options. Calling $(..).scrollspy(...) again on the same element ignores any new data options (uses the previously initialized values).

但是,滚动确实将选项值存储在键'bs.scrollspy'下的元素数据中.因此,您可以更改该数据密钥内的options.offset字段.

However, scrollspy does store the options values in the elements data under the key 'bs.scrollspy'. So you can alter the options.offset field inside that data key.

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

To account for a dynamically changing navbar height and the need to alter the scrollspy offset value, you can use the following example for a variable height fixed-top navbar.

以下内容可做一些事情.

The following does a few of things.

  • 它通过javascript(在window.load事件触发后)初始化scrollspy,并以导航栏当前高度的偏移量开始(也将主体的padding-top值调整为与导航栏高度相同).
  • li> 监视
  • 调整大小事件并调整主体的padding-top,并调整卷轴offset以使其匹配.然后执行refresh重新计算锚点偏移量.
  • It initializes scrollspy via javascript (after the window.load event fires), and starts off with an offset of the navbar's current height (also adjusts the body's padding-top value to be the same as the navbar height).
  • Resize events are monitored and the body's padding-top is adjusted, and the scrollspy offset is tweaked to match. Then a refresh is performed to recalculate the anchor offsets.
<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>

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);
    });
});

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

And thats it. Not pretty, but it definitely works. My HTML above may need some tweaking.

如果将元素动态添加到导航栏,则在插入fixSpy()后需要调用它们.或者,您可以通过setInterval(...)计时器调用fixSpy()来始终运行.

If you add elements to your navbar dynamically you will need to call fixSpy() after they are inserted. Or you could call fixSpy() via a setInterval(...) timer to run all the time.

这篇关于Bootstrap 3.0 scrollspy响应式偏移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆