导航栏悬浮定位效果的实现思路
需求说明
最近网站改版,需要实现一个悬浮定位导航栏,类似效果见下图(Bootstrap页面示例):

本篇博文将主要讲述该效果的具体实现细节,实现依赖于Bootstrap框架。
搭建框架
首先,整个html页面的基础框架结构是这样的:
<div class="col-md-3">
<ul id="nav" class="nav hidden-xs hidden-sm">
<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>
我们将页面划分为3:9的两部分,左侧为导航栏,右侧为具体内容。
在这个例子中,我们希望当屏幕缩小到一定比例时,悬浮定位导航栏自动隐藏,因此我们为导航添加了hidden-xs和hidden-sm类。
每一个<section>都有一个id,对应着<a>标签中的href属性,即锚点。
Affix控件
Bootstrap的Affix控件在这里的主要功能是实现当页面向下滑动时导航栏的悬停效果,要使用Affix控件很容易,直接将data-spy="affix"添加到导航栏上就好。
<ul id="nav" class="nav hidden-xs hidden-sm" data-spy="affix" data-offset-top="380" >
注意上图中的data-offset-top属性,它设置的是导航栏距离顶部多少像素时开始悬停。
下面稍稍解释下本例中Affix控件的工作流程:
1.初始状态下,我们可以注意到控件将affix-top添加导航栏的类中:

2.当页面滚动超过我们设定的像素距离后,控件用affix替换了affix-top:

这时我们可以通过设置css样式调整导航栏悬停时的效果:
.affix {
top: 20px;
width: 213px;
}
ScrollSpy控件
Bootstrap的滚动监听ScrollSpy控件在这里的作用是当页面主体内容改变时,导航条也要有对应的变化(子章节的展开、高亮等)。
ScrollSpy控件依赖Bootstrap的导航控件用于高亮当前激活的链接。
同时,需要被监听的组件是position: relative;,即相对定位方式,大多时候是监听body元素。
我们可以通过data属性调用ScrollSpy控件,将data-spy="scroll"添加到你希望监听的元素上(<body>),同时将data-target设置为本例中导航栏的class:
<body data-spy="scroll" data-target=".scrollspy">
<!-- content here... -->
<div class="col-md-3 scrollspy">
<ul id="nav" class="nav hidden-xs hidden-sm" data-spy="affix">
<!-- nav items here... -->
</ul>
</div>
<!-- content here... -->
</body>
记得设置<body>元素的CSS:
body {
position: relative;
}
当用户滑动鼠标滚轮,页面内容发生变化时,我们可以观察到ScrollSpy控件将active添加到对应导航栏中的<li>元素的类中:

接下来要做的就是为导航栏的各种状态添加一些css效果即可:
.nav .active {
font-weight: bold;
background: #72bcd4;
}
.nav .nav {
display: none;
}
.nav .active .nav {
display: block;
}
.nav .nav a {
font-weight: normal;
font-size: .85em;
}
.nav .nav span {
margin: 0 5px 0 2px;
}
.nav .nav .active a,
.nav .nav .active:hover a,
.nav .nav .active:focus a {
font-weight: bold;
padding-left: 30px;
border-left: 5px solid black;
}
.nav .nav .active span,
.nav .nav .active:hover span,
.nav .nav .active:focus span {
display: none;
}
