Bootstrap 滚动监听(Scrollspy)插件

滚动监听(Scrollspy)插件,即自动更新导航插件,会根据滚动条的位置自动更新对应的导航目标。其基本的实现是随着您的滚动,基于滚动条的位置向导航栏添加 .active class。

如果您想要单独引用该插件的功能,那么您需要引用 scrollspy.js。或者,正如 Bootstrap 插件概览 一章中所提到,您可以引用 bootstrap.js 或压缩版的 bootstrap.min.js

用法

您可以向顶部导航添加滚动监听行为:

  • 通过 data 属性:向您想要监听的元素(通常是 body)添加 data-spy="scroll"。然后添加带有 Bootstrap .nav 组件的父元素的 ID 或 class 的属性 data-target。为了它能正常工作,您必须确保页面主体中有匹配您所要监听链接的 ID 的元素存在。

    <body data-spy="scroll" data-target=".navbar-example">
    ...
    <div>
        <ul>
            ...
        </ul>
    </div>
    ...
    </body>
  • 通过 JavaScript:您可以通过 JavaScript 调用滚动监听,选取要监听的元素,然后调用 .scrollspy() 函数:

    $('body').scrollspy({ target: '.navbar-example' })

在线示例

下面的示例演示了通过 data 属性使用滚动监听(Scrollspy)插件:

在线示例

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"> 
	<title>Bootstrap 示例 - 滚动监听(Scrollspy)插件</title>
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav id="navbar-example" class="navbar navbar-default navbar-static" role="navigation">
	<div class="container-fluid"> 
		<div class="navbar-header">
			<button class="navbar-toggle" type="button" data-toggle="collapse" 
					data-target=".bs-js-navbar-scrollspy">
				<span class="sr-only">切换导航</span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			</button>
			<a class="navbar-brand" href="#">教程名称</a>
		</div>
		<div class="collapse navbar-collapse bs-js-navbar-scrollspy">
			<ul class="nav navbar-nav">
				<li><a href="#ios">iOS</a></li>
				<li><a href="#svn">SVN</a></li>
				<li class="dropdown">
					<a href="#" id="navbarDrop1" class="dropdown-toggle" 
					   data-toggle="dropdown">Java
						<b class="caret"></b>
					</a>
					<ul class="dropdown-menu" role="menu" 
						aria-labelledby="navbarDrop1">
						<li><a href="#jmeter" tabindex="-1">jmeter</a></li>
						<li><a href="#ejb" tabindex="-1">ejb</a></li>
						<li class="divider"></li>
						<li><a href="#spring" tabindex="-1">spring</a></li>
					</ul>
				</li>
			</ul>
		</div>
	</div> 
</nav>
<div data-spy="scroll" data-target="#navbar-example" data-offset="0" 
	 style="height:200px;overflow:auto; position: relative;">
	<h4 id="ios">iOS</h4>
	<p>iOS 是一个由苹果公司开发和发布的手机操作系统。最初是于 2007 年首次发布 iPhone、iPod Touch 和 Apple 
		TV。iOS 派生自 OS X,它们共享 Darwin 基础。OS X 操作系统是用在苹果电脑上,iOS 是苹果的移动版本。
	</p>
	<h4 id="svn">SVN</h4>
	<p>Apache Subversion,通常缩写为 SVN,是一款开源的版本控制系统软件。Subversion 由 CollabNet 公司在 2000 年创建。但是现在它已经发展为 Apache Software Foundation 的一个项目,因此拥有丰富的开发人员和用户社区。
	</p>
	<h4 id="jmeter">jMeter</h4>
	<p>jMeter 是一款开源的测试软件。它是 100% 纯 Java 应用程序,用于负载和性能测试。
	</p>
	<h4 id="ejb">EJB</h4>
	<p>Enterprise Java Beans(EJB)是一个创建高度可扩展性和强大企业级应用程序的开发架构,部署在兼容应用程序服务器(比如 JBOSS、Web Logic 等)的 J2EE 上。
	</p>
	<h4 id="spring">Spring</h4>
	<p>Spring 框架是一个开源的 Java 平台,为快速开发功能强大的 Java 应用程序提供了完备的基础设施支持。
	</p>
	<p>Spring 框架最初是由 Rod Johnson 编写的,在 2003 年 6 月首次发布于 Apache 2.0 许可证下。
	</p>
</div>
</body>
</html>
测试看看 ‹/›

结果如下所示:

滚动监听(Scrollspy)插件

选项

通过 data 属性或 JavaScript 来传递。下表列出了这些选项:

选项名称类型/默认值Data 属性名称描述
offsetnumber
默认值:10
data-offset当计算滚动位置时,距离顶部的偏移像素。

方法

.scrollspy('refresh'):当通过 JavaScript 调用 scrollspy 方法时,您需要调用 .refresh 方法来更新 DOM。这在 DOM 的任意元素发生变更(即,您添加或移除了某些元素)时非常有用。下面是使用该方法的语法。

$('[data-spy="scroll"]').each(function () {
  var $spy = $(this).scrollspy('refresh')
})

在线示例

下面的示例演示了 .scrollspy('refresh') 方法的用法:

在线示例

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Bootstrap 示例 - 滚动监听(Scrollspy)插件方法</title>
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav id="myScrollspy" class="navbar navbar-default navbar-static" role="navigation">
	<div class="container-fluid"> 
		<div class="navbar-header">
			<button class="navbar-toggle" type="button" data-toggle="collapse" 
					data-target=".bs-js-navbar-scrollspy">
				<span class="sr-only">切换导航</span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			</button>
			<a class="navbar-brand" href="#">教程名称</a>
		</div>
		<div class="collapse navbar-collapse bs-js-navbar-scrollspy">
			<ul class="nav navbar-nav">
				<li class="active"><a href="#ios">iOS</a></li>
				<li><a href="#svn">SVN</a></li>
				<li class="dropdown">
					<a href="#" id="navbarDrop1" class="dropdown-toggle" 
					   data-toggle="dropdown">Java 
						<b class="caret"></b>
					</a>
					<ul class="dropdown-menu" role="menu" 
						aria-labelledby="navbarDrop1">
						<li><a href="#jmeter" tabindex="-1">jmeter</a></li>
						<li><a href="#ejb" tabindex="-1">ejb</a></li>
						<li class="divider"></li>
						<li><a href="#spring" tabindex="-1">spring</a></li>
					</ul>
				</li>
			</ul>
		</div>
	</div>
</nav>
<div data-spy="scroll" data-target="#myScrollspy" data-offset="0" 
	 style="height:200px;overflow:auto; position: relative;">
	<div class="section">
		<h4 id="ios">iOS<small><a href="#" onclick="removeSection(this);">
			&times; 删除该部分</a></small>
		</h4>
		<p>iOS 是一个由苹果公司开发和发布的手机操作系统。最初是于 2007 年首次发布 iPhone、iPod Touch 和 Apple 
			TV。iOS 派生自 OS X,它们共享 Darwin 基础。OS X 操作系统是用在苹果电脑上,iOS 是苹果的移动版本。</p>
	</div>
	<div class="section">
		<h4 id="svn">SVN<small></small></h4>
		<p>Apache Subversion,通常缩写为 SVN,是一款开源的版本控制系统软件。Subversion 由 CollabNet 公司在 2000 年创建。但是现在它已经发展为 Apache Software Foundation 的一个项目,因此拥有丰富的开发人员和用户社区。</p>
	</div>
	<div class="section">
		<h4 id="jmeter">jMeter<small><a href="#" onclick="removeSection(this);">
			&times; 删除该部分</a></small>
		</h4>
		<p>jMeter 是一款开源的测试软件。它是 100% 纯 Java 应用程序,用于负载和性能测试。</p>
	</div>
	<div class="section">
		<h4 id="ejb">EJB</h4>
		<p>Enterprise Java Beans(EJB)是一个创建高度可扩展性和强大企业级应用程序的开发架构,部署在兼容应用程序服务器(比如 JBOSS、Web Logic 等)的 J2EE 上。</p>
	</div>
	<div class="section">
		<h4 id="spring">Spring</h4>
		<p>Spring 框架是一个开源的 Java 平台,为快速开发功能强大的 Java 应用程序提供了完备的基础设施支持。</p>
		<p>Spring 框架最初是由 Rod Johnson 编写的,在 2003 年 6 月首次发布于 Apache 2.0 许可证下。</p>
	</div>
</div>
<script type="text/javascript">
	$(function(){
		removeSection = function(e) {
			$(e).parents(".section").remove();
			$('[data-spy="scroll"]').each(function () {
				var $spy = $(this).scrollspy('refresh')
				});
		}
		$("#myScrollspy").scrollspy();
});
</script>
</body>
</html>
测试看看 ‹/›

结果如下所示:

滚动监听(Scrollspy)插件方法

事件

下表列出了滚动监听中要用到事件。这些事件可在函数中当钩子使用。

事件描述示例
activate.bs.scrollspy每当一个新项目被滚动监听激活时,触发该事件。
$('#myScrollspy').on('activate.bs.scrollspy', function () {
  // 执行一些动作...
})

在线示例

下面的示例演示了 activate.bs.scrollspy 事件的用法:

在线示例

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Bootstrap 示例 - 滚动监听(Scrollspy)插件事件</title>
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<nav id="myScrollspy" class="navbar navbar-default navbar-static" role="navigation">
	<div class="container-fluid"> 
		<div class="navbar-header">
			<button class="navbar-toggle" type="button" data-toggle="collapse" 
					data-target=".bs-js-navbar-scrollspy">
				<span class="sr-only">切换导航</span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			</button>
			<a class="navbar-brand" href="#">教程名称</a>
		</div>
		<div class="collapse navbar-collapse bs-js-navbar-scrollspy">
			<ul class="nav navbar-nav">
				<li class="active"><a href="#ios">iOS</a></li>
				<li><a href="#svn">SVN</a></li>
				<li class="dropdown">
					<a href="#" id="navbarDrop1" class="dropdown-toggle" 
					   data-toggle="dropdown">
						Java <b class="caret"></b>
					</a>
					<ul class="dropdown-menu" role="menu" 
						aria-labelledby="navbarDrop1">
						<li><a href="#jmeter" tabindex="-1">jmeter</a></li>
						<li><a href="#ejb" tabindex="-1">ejb</a></li>
						<li class="divider"></li>
						<li><a href="#spring" tabindex="-1">spring</a></li>
					</ul>
				</li>
			</ul>
		</div>
	</div>
</nav>
<div data-spy="scroll" data-target="#myScrollspy" data-offset="0" 
	 style="height:200px;overflow:auto; position: relative;">
	<div class="section">
		<h4 id="ios">iOS<small><a href="#" onclick="removeSection(this);">
			&times; 删除该部分</a></small>
		</h4>
		<p>iOS 是一个由苹果公司开发和发布的手机操作系统。最初是于 2007 年首次发布 iPhone、iPod Touch 和 Apple 
			TV。iOS 派生自 OS X,它们共享 Darwin 基础。OS X 操作系统是用在苹果电脑上,iOS 是苹果的移动版本。</p>
	</div>
	<div class="section">
		<h4 id="svn">SVN<small></small></h4>
		<p>Apache Subversion,通常缩写为 SVN,是一款开源的版本控制系统软件。Subversion 由 CollabNet 公司在 2000 年创建。但是现在它已经发展为 Apache Software Foundation 的一个项目,因此拥有丰富的开发人员和用户社区。</p>
	</div>
	<div class="section">
		<h4 id="jmeter">jMeter<small><a href="#" onclick="removeSection(this);">
			&times; 删除该部分</a></small>
		</h4>
		<p>jMeter 是一款开源的测试软件。它是 100% 纯 Java 应用程序,用于负载和性能测试。</p>
	</div>
	<div class="section">
		<h4 id="ejb">EJB</h4>
		<p>Enterprise Java Beans(EJB)是一个创建高度可扩展性和强大企业级应用程序的开发架构,部署在兼容应用程序服务器(比如 JBOSS、Web Logic 等)的 J2EE 上。</p>
	</div>
	<div class="section">
		<h4 id="spring">Spring</h4>
		<p>Spring 框架是一个开源的 Java 平台,为快速开发功能强大的 Java 应用程序提供了完备的基础设施支持。</p>
		<p>Spring 框架最初是由 Rod Johnson 编写的,在 2003 年 6 月首次发布于 Apache 2.0 许可证下。</p>
	</div>
</div>
<span id="activeitem" style="color:red;"></span>
<script type="text/javascript">
	$(function(){
		removeSection = function(e) {
			$(e).parents(".section").remove();
			$('[data-spy="scroll"]').each(function () {
				var $spy = $(this).scrollspy('refresh')
				});
		}
		$("#myScrollspy").scrollspy();
		$('#myScrollspy').on('activate.bs.scrollspy', function () {
			var currentItem = $(".nav li.active > a").text();
			$("#activeitem").html("目前您正在查看 - " + currentItem);
		})
});
</script>
</body>
</html>
测试看看 ‹/›

结果如下所示:

滚动监听(Scrollspy)插件事件

更多示例

创建水平滚动监听

以下示例演示了如何创建水平滚动监听:

在线示例

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Bootstrap Example</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
	<style>
		body {
			position: relative; 
		}
		#section1 {padding-top:50px;height:500px;color: #fff; background-color: #1E88E5;}
		#section2 {padding-top:50px;height:500px;color: #fff; background-color: #673ab7;}
		#section3 {padding-top:50px;height:500px;color: #fff; background-color: #ff9800;}
		#section41 {padding-top:50px;height:500px;color: #fff; background-color: #00bcd4;}
		#section42 {padding-top:50px;height:500px;color: #fff; background-color: #009688;}
	</style>
</head>
<body data-spy="scroll" data-target=".navbar" data-offset="50">
<nav class="navbar navbar-inverse navbar-fixed-top">
	<div class="container-fluid">
		<div class="navbar-header">
			<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#myNavbar">
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>                        
			</button>
			<a class="navbar-brand" href="#">WebSiteName</a>
		</div>
		<div>
			<div class="collapse navbar-collapse" id="myNavbar">
				<ul class="nav navbar-nav">
					<li><a href="#section1">Section 1</a></li>
					<li><a href="#section2">Section 2</a></li>
					<li><a href="#section3">Section 3</a></li>
					<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Section 4 <span class="caret"></span></a>
						<ul class="dropdown-menu">
							<li><a href="#section41">Section 4-1</a></li>
							<li><a href="#section42">Section 4-2</a></li>
						</ul>
					</li>
				</ul>
			</div>
		</div>
	</div>
</nav>    
<div id="section1" class="container-fluid">
	<h1>Section 1</h1>
	<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
	<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
	</div>
	<div id="section2" class="container-fluid">
		<h1>Section 2</h1>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
	</div>
	<div id="section3" class="container-fluid">
		<h1>Section 3</h1>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
	</div>
	<div id="section41" class="container-fluid">
		<h1>Section 4 Submenu 1</h1>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
	</div>
	<div id="section42" class="container-fluid">
		<h1>Section 4 Submenu 2</h1>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
		<p>尝试滚动此部分并在滚动时查看导航栏!尝试滚动此部分,并在滚动时查看导航栏!</p>
</div>
</body>
</html>
测试看看 ‹/›

如何创建垂直滚动监听

以下示例演示了如何创建垂直滚动监听:

在线示例

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Bootstrap 示例</title>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
	<style>
		body {
			position: relative;
		}
		ul.nav-pills {
			top: 20px;
			position: fixed;
		}
		div.col-sm-9 div {
			height: 250px;
			font-size: 28px;
		}
		#section1 {color: #fff; background-color: #1E88E5;}
		#section2 {color: #fff; background-color: #673ab7;}
		#section3 {color: #fff; background-color: #ff9800;}
		#section41 {color: #fff; background-color: #00bcd4;}
		#section42 {color: #fff; background-color: #009688;}
		@media screen and (max-width: 810px) {
			#section1, #section2, #section3, #section41, #section42  {
				margin-left: 150px;
			}
		}
	</style>
</head>
<body data-spy="scroll" data-target="#myScrollspy" data-offset="20">
<div class="container">
	<div class="row">
		<nav class="col-sm-3" id="myScrollspy">
			<div class="container-fluid"> 
			<div class="container-fluid"> 
			<ul class="nav nav-pills nav-stacked">
				<li class="active"><a href="#section1">Section 1</a></li>
				<li><a href="#section2">Section 2</a></li>
				<li><a href="#section3">Section 3</a></li>
				<li class="dropdown">
					<a class="dropdown-toggle" data-toggle="dropdown" href="#">Section 4 <span class="caret"></span></a>
					<ul class="dropdown-menu">
						<li><a href="#section41">Section 4-1</a></li>
						<li><a href="#section42">Section 4-2</a></li>                     
					</ul>
				</li>
			</ul>
			</div>	
			</div>		
		</nav>
		<div class="col-sm-9">
			<div id="section1">    
				<h1>Section 1</h1>
				<p>尝试滚动此部分并在滚动时查看导航列表!</p>
			</div>
			<div id="section2"> 
				<h1>Section 2</h1>
				<p>尝试滚动此部分并在滚动时查看导航列表!</p>
			</div>        
			<div id="section3">         
				<h1>Section 3</h1>
				<p>尝试滚动此部分并在滚动时查看导航列表!</p>
			</div>
			<div id="section41">         
				<h1>Section 4-1</h1>
				<p>尝试滚动此部分并在滚动时查看导航列表!</p>
			</div>      
			<div id="section42">         
				<h1>Section 4-2</h1>
				<p>尝试滚动此部分并在滚动时查看导航列表!</p>
			</div>
		</div>
	</div>
</div>
</body>
</html>
测试看看 ‹/›