大家在浏览Bootstrap网站的时候应该注意到了,页面右边栏的导航会跟随页面的滚动而变动。这个效果可以由Bootstrap的jQuery组件:Affix与 scrollspy 整合来实现。
这篇文章我们将为大家演示如果在你的网站中增加这样的效果。为了大家更好的理解,我们用下面这个例子来演示。
前面曾分享过一篇《Bootstrap之Affix用法详解及示例》的文章,这篇将比那一篇更加详尽。
我们先从它的页面结构开始。
页面的基本结构
对于小屏幕,我们使用一列布局,而对于大中型屏幕,我们使用两列布局。一部分是我们的导航,占用了四分之一宽度,另一部分是主要内容,占用剩下的四分之三。页面中每一个的id
属性要与导航中a
标签的href
属性相同。
因为我们的例子中只有大中型屏幕(宽度大于等于991px)上显示,所以我们给导航的class
加上了hidden-xs
和hidden-sm
。来看下面的代码,为简便起见,我们这里并没有写技术部分详细内容。
<div class="col-md-3 scrollspy"> <ul id="nav" class="nav hidden-xs hidden-sm" data-spy="affix"> <li><a href="#web-design">Web Design</a></li> <li> <a href="#web-development">Web Development</a> <ul class="nav"> <li><a href="#ruby"><span class="fa fa-angle-double-right"></span>Ruby</a></li> <li><a href="#python"><span class="fa fa-angle-double-right"></span>Python</a></li> </ul><!--end of sub navigation--> </li> </ul><!-- end of main navigation --> </div> <div class="col-md-9"> <section id="web-design"></section> <section id="web-development"> <section id="ruby"></section> <section id="python"></section> </section> </div>
理解了上面的页面结构之后,我们引入插件来实现功能。
使用Affix
Affix插件可以帮助我们固定导航部分的位置,并且根据用户的滚动情况来为固定的元素增加垂直偏移量。为了使用Affix插件,我们需要指定一个元素来接受“affix
”行为。我们只需要给它增加一个data-spy="affix"
属性/值。在我们的例子中,需要给UL
元素增加此属性/值。
这个插件在下面三个class
直接切换:
affix-top
:表示在最顶端位置;affix
:当元素开始在页面中滚动时的属性,并且会为元素增加fixed
属性;affix-bottom
:到达最低端位置。
简单的说就是,当页面上下滚动时,通过上面三个class属性来切换元素的位置。
PS:我们可以随意使用上面三个class属性。其中最重要的是affix
,它使的用户向下滚动页面时让元素固定在页面中。然而,根据我们的页面结构,我们也需要使用affix-top
和affix-bottom
。
下面我们看看如何在我们的例子中引入上面三个class属性。
首先给ul
增加affix-top
属性。我们可以通过增加data-*
属性或者JavaScript方法。这里我们使用的是jQuery/JavaScript方法。
$('#nav').affix({ offset: { top: $('#nav').offset().top } });
通过上面方法,我们已经固定了导航距离顶部的位置。大概是390px。默认情况下,它的位置被设定为static
。虽然Bootstrap并没有提到它的CSS定位是必须的,我们还是给它设置成了relative
。下面的截图附带了注释说明。
当页面初次加载的时候,HTML中ul
元素的会是如下形式:
正如你看到的,当用户刚开始滚动页面的时候,ul
元素的class
属性是affix-top
。当滚动到元素的初始top位置(大约390px)时,ul
的class
属性变成affix
,并且位置变成了fixed
,这时我们重新更改了它的top
位置和width
属性,下面是相关的样式:
.affix { top: 20px; width: 213px; } @media (min-width: 1200px) { .affix { width: 263px; } }
下面是相关截图:
以及生成的相关的HTML代码:
当用户滚动页面的时候,ul
被固定在页面顶部。当然,这是一个非常棒的效果,但我们也需要停止固定,这时就需要用到affix-bottom
属性。为了使插件触发这个效果,我们需要知道目标元素与底部的偏移量。这里也可以通过通常的data-*
属性或者jQuery/Javascript方法。下面是jQuery方法:
$('#nav').affix({ offset: { bottom: ($('footer').outerHeight(true) + $('.application').outerHeight(true)) + 40 } });
这一阶段我们必须指定元素的CSS position
属性。 我们可以使用position: absolute
或者position: relative
。此例我们使用第一种。同时我们还要指定width
属性。下面是必要的样式:
.affix-bottom { position: absolute; width: 213px; } @media (min-width: 1200px) { .affix-bottom { width: 263px; } }
最后阶段,我们的例子看起来是下面的样子:
以及HTML结构:
如上所示,jQuery根据我们定义的bottom
偏移量,为元素应用了新的top
偏移量。
PS:这部分最重要的一点是我们需要给元素增加底部偏移量,否则页面看起来可能会是这样:
现在,我们已经完成了affix功能,可以增加ScrollSpy功能了。
此功能留在下一篇文章中分享。
via:SitePoint
IT疯狂女 2015/02/17 11:33
代码大大好哇
Specs 2015/02/25 10:23
@ 新年好~
fengshiyunji 2015/04/06 17:25
你好,我还是没有看懂你的例子,
Specs 2015/04/07 21:02
@ 已经很详细了啊,可以下载源代码再仔细研究研究
prentice 2015/04/21 10:19
再请都教一下,如果像右侧的tab“热点-最新-随机”这个栏目,也就是初始位置在中间或偏下,如何用affix实现,请赐教
Specs 2015/04/22 10:09
@ 这个不是用 affix 来做的
zhizunbao84 2015/08/05 08:33
博主,你好,我想请问下,如果affix部分的高度超过正文部分,会造成错位,这个怎么解决啊
Specs 2015/08/05 14:18
@ 我是先判断正文的高度很affix部分的高度,如果正文的大于affix部分,才启用 affix 这个
zhizunbao84 2015/08/05 08:35
博主,你好,我想请问下,如果affix部分的高度超过正文部分,当滚动到最下面时,变成ffix-bottom后,top会变成负数,会造成错位,这个怎么解决啊
Specs 2015/08/05 14:20
@ if($("#main").height() > $("#sidebar").height()){/*执行affix*/} 类似这样的判断
jerry 2018/01/31 19:10
楼主还在吗?请教下 如果顶部Bar fixed后。。点击导航的时候调到对面锚点 位置不对。。被fixed的导航栏高度挡住了 怎么调呢,查不到具体方法。用scrollspy的data-offset也没用。。